perm filename CLCOMP.2[COM,LSP] blob
sn#870942 filedate 1989-03-13 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00591 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00089 00002
C00090 00003 ∂12-Dec-88 0756 CL-Compiler-mailer Re: Objects in quoted constants
C00093 00004 ∂12-Dec-88 1159 CL-Compiler-mailer issue CONSTANT-MODIFICATION, version 2
C00098 00005 ∂12-Dec-88 1212 CL-Compiler-mailer issue CONSTANT-COLLAPSING, version 2
C00103 00006 ∂12-Dec-88 1327 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 3
C00112 00007 ∂12-Dec-88 1344 CL-Compiler-mailer issue status, 12/12/88
C00118 00008 ∂12-Dec-88 1425 CL-Compiler-mailer Re: issue CONSTANT-COLLAPSING, version 2
C00120 00009 ∂12-Dec-88 1434 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 3
C00123 00010 ∂12-Dec-88 1434 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00127 00011 ∂12-Dec-88 1454 CL-Compiler-mailer Re: issue status, 12/12/88
C00131 00012 ∂12-Dec-88 1456 CL-Compiler-mailer Issue: COMPILER-VERBOSITY (Version 2)
C00142 00013 ∂12-Dec-88 1619 CL-Compiler-mailer Re: issue status, 12/12/88
C00145 00014 ∂12-Dec-88 1700 CL-Compiler-mailer Re: issue status, 12/12/88 (issue COMPILER-DIAGNOSTICS)
C00149 00015 ∂12-Dec-88 1726 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 3
C00152 00016 ∂12-Dec-88 1749 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00155 00017 ∂13-Dec-88 1154 CL-Compiler-mailer Re: issue status, 12/12/88 (issue COMPILER-DIAGNOSTICS)
C00163 00018 ∂13-Dec-88 1340 CL-Compiler-mailer Re: issue status, 12/12/88 (issue COMPILER-DIAGNOSTICS)
C00165 00019 ∂13-Dec-88 2003 CL-Compiler-mailer issue CONSTANT-COLLAPSING, version 2
C00169 00020 ∂14-Dec-88 0035 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 2
C00173 00021 ∂14-Dec-88 0146 CL-Compiler-mailer I still need help with compile-time side-effects
C00175 00022 ∂14-Dec-88 0814 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00179 00023 ∂14-Dec-88 0902 CL-Compiler-mailer Re: issue CONSTANT-COLLAPSING, version 2
C00182 00024 ∂14-Dec-88 0951 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00185 00025 ∂14-Dec-88 1300 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 1
C00188 00026 ∂15-Dec-88 0832 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00191 00027 ∂15-Dec-88 0843 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00193 00028 ∂15-Dec-88 1208 CL-Compiler-mailer Issue: COMPILER-VERBOSITY (Version 3)
C00203 00029 ∂15-Dec-88 1207 CL-Compiler-mailer Issue: COMPILER-DIAGNOSTICS (Version 5)
C00220 00030 ∂15-Dec-88 1213 CL-Compiler-mailer Re: Issue: COMPILER-DIAGNOSTICS (Version 5)
C00222 00031 ∂15-Dec-88 1853 CL-Compiler-mailer dumping weird objects to compiled files
C00226 00032 ∂16-Dec-88 0141 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 2
C00228 00033 ∂16-Dec-88 0733 CL-Compiler-mailer Re: dumping weird objects to compiled files
C00231 00034 ∂16-Dec-88 0843 Common-Lisp-mailer Re: dumping weird objects to compiled files
C00234 00035 ∂16-Dec-88 1254 CL-Compiler-mailer quoted constants
C00237 00036 ∂16-Dec-88 1258 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 7
C00261 00037 ∂16-Dec-88 1433 CL-Compiler-mailer issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
C00279 00038 ∂16-Dec-88 1547 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 7
C00281 00039 ∂16-Dec-88 1617 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 2
C00289 00040 ∂16-Dec-88 1620 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 5
C00297 00041 ∂17-Dec-88 1339 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00300 00042 ∂17-Dec-88 1359 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00303 00043 ∂17-Dec-88 1718 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00309 00044 ∂17-Dec-88 2029 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00313 00045 ∂18-Dec-88 2106 CL-Compiler-mailer Re: quoted constants
C00316 00046 ∂20-Dec-88 1212 CL-Compiler-mailer Re: issue COMPILER-DIAGNOSTICS, version 7
C00320 00047 ∂20-Dec-88 1214 CL-Compiler-mailer Re: issue COMPILER-DIAGNOSTICS, version 7
C00323 00048 ∂20-Dec-88 1224 CL-Compiler-mailer Re: issue COMPILER-DIAGNOSTICS, version 7
C00326 00049 ∂20-Dec-88 1707 CL-Compiler-mailer CONSTANT-COMPILABLE-TYPES:SPECIFY, V4
C00350 00050 ∂21-Dec-88 0455 CL-Compiler-mailer RE: Re: issue COMPILER-DIAGNOSTICS, version 7
C00353 00051 ∂21-Dec-88 0818 CL-Compiler-mailer Re: CONSTANT-COMPILABLE-TYPES:SPECIFY, V4
C00357 00052 ∂21-Dec-88 1224 CL-Compiler-mailer Summary of active issues, 12/21/88
C00363 00053 ∂21-Dec-88 1223 CL-Compiler-mailer issue COMPILER-VERBOSITY, version 4
C00375 00054 ∂22-Dec-88 1110 CL-Compiler-mailer RE: Re: issue COMPILER-DIAGNOSTICS, version 7
C00380 00055 ∂22-Dec-88 1137 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 2
C00384 00056 ∂22-Dec-88 1140 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 5
C00388 00057 ∂22-Dec-88 1141 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 2
C00391 00058 ∂22-Dec-88 1433 CL-Compiler-mailer Re: CONSTANT-COMPILABLE-TYPES:SPECIFY, V4
C00395 00059 ∂22-Dec-88 1601 CL-Compiler-mailer Issue ALLOW-LOCAL-INLINE (V3)
C00400 00060 ∂22-Dec-88 1650 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, V3
C00408 00061 ∂23-Dec-88 0643 CL-Compiler-mailer RE: Issue ALLOW-LOCAL-INLINE (V3)
C00410 00062 ∂23-Dec-88 0910 CL-Compiler-mailer RE: Issue ALLOW-LOCAL-INLINE (V3)
C00415 00063 ∂23-Dec-88 0908 CL-Compiler-mailer Issue: QUOTE-MAY-COPY (Version 2)
C00421 00064 ∂23-Dec-88 1153 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00427 00065 ∂23-Dec-88 1236 CL-Compiler-mailer issue DEFCONSTANT-SPECIAL, version 2
C00433 00066 ∂23-Dec-88 1237 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 7
C00438 00067 ∂23-Dec-88 1245 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
C00442 00068 ∂23-Dec-88 1452 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 7
C00447 00069 ∂27-Dec-88 1204 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
C00450 00070 ∂27-Dec-88 1206 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, V3
C00455 00071 ∂27-Dec-88 1216 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 2
C00458 00072 ∂27-Dec-88 1705 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
C00465 00073 ∂29-Dec-88 0312 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
C00470 00074 ∂29-Dec-88 0500 Common-Lisp-Object-System-mailer Compilation implications
C00478 00075 ∂29-Dec-88 0654 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
C00487 00076 ∂29-Dec-88 1001 Common-Lisp-Object-System-mailer Compilation implications
C00497 00077 ∂29-Dec-88 1804 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
C00502 00078 ∂29-Dec-88 2213 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
C00507 00079 ∂30-Dec-88 0108 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
C00511 00080 ∂30-Dec-88 0400 CL-Compiler-mailer Compilation implications
C00514 00081 ∂30-Dec-88 0533 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
C00518 00082 ∂30-Dec-88 1053 CL-Compiler-mailer I'm back
C00520 00083 ∂30-Dec-88 1128 CL-Compiler-mailer Re: Compilation implications
C00528 00084 ∂30-Dec-88 1132 CL-Compiler-mailer Re: issue COMPILER-DIAGNOSTICS, version 7
C00532 00085 ∂30-Dec-88 1220 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
C00537 00086 ∂30-Dec-88 1303 CL-Compiler-mailer issue DEFCONSTANT-SPECIAL, version 3
C00544 00087 ∂30-Dec-88 1304 CL-Compiler-mailer issue ALLOW-LOCAL-INLINE, version 4
C00554 00088 ∂30-Dec-88 1334 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 5
C00559 00089 ∂30-Dec-88 1335 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 3
C00567 00090 ∂30-Dec-88 1351 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
C00570 00091 ∂30-Dec-88 1520 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 2
C00578 00092 ∂30-Dec-88 1601 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 8
C00595 00093 ∂30-Dec-88 1940 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 7
C00598 00094 ∂30-Dec-88 2008 CL-Compiler-mailer Compilation implications
C00603 00095 ∂31-Dec-88 1036 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00607 00096 ∂31-Dec-88 1151 CL-Compiler-mailer issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 8
C00626 00097 ∂31-Dec-88 1224 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
C00635 00098 ∂31-Dec-88 1401 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00639 00099 ∂31-Dec-88 1943 CL-Compiler-mailer Issue COMPILER-LET-CONFUSION, v3
C00642 00100 ∂31-Dec-88 1946 CL-Compiler-mailer Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, v7
C00647 00101 ∂31-Dec-88 1951 CL-Compiler-mailer Issue DEFINING-MACROS-NON-TOP-LEVEL, v5
C00649 00102 ∂31-Dec-88 1953 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00654 00103 ∂31-Dec-88 1956 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
C00658 00104 ∂31-Dec-88 1959 CL-Compiler-mailer environment arguments and compiler contexts and ...
C00666 00105 ∂01-Jan-89 0258 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
C00668 00106 ∂01-Jan-89 0510 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
C00670 00107 ∂01-Jan-89 1022 CL-Compiler-mailer Re: environment arguments and compiler contexts and ...
C00675 00108 ∂01-Jan-89 1243 CL-Compiler-mailer Re: environment arguments and compiler contexts and ...
C00680 00109 ∂01-Jan-89 2050 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00683 00110 ∂01-Jan-89 2055 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
C00685 00111 ∂02-Jan-89 0015 CL-Compiler-mailer Issue COMPILER-LET-CONFUSION, v3
C00688 00112 ∂02-Jan-89 0222 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
C00691 00113 ∂02-Jan-89 1328 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 1)
C00701 00114 ∂02-Jan-89 1912 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00704 00115 ∂02-Jan-89 2053 CL-Compiler-mailer issue COMPILE-ARGUMENT-PROBLEMS
C00713 00116 ∂02-Jan-89 2058 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00717 00117 ∂02-Jan-89 2104 CL-Compiler-mailer Re: issue COMPILE-ARGUMENT-PROBLEMS
C00724 00118 ∂02-Jan-89 2119 CL-Compiler-mailer Re: issue COMPILE-ARGUMENT-PROBLEMS
C00728 00119 ∂02-Jan-89 2209 CL-Compiler-mailer Re: issue COMPILE-ARGUMENT-PROBLEMS
C00732 00120 ∂02-Jan-89 2305 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
C00736 00121 ∂03-Jan-89 0118 CL-Compiler-mailer Re: Issue COMPILE-ARGUMENT-PROBLEMS
C00739 00122 ∂03-Jan-89 0857 CL-Compiler-mailer Re: Issue: DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES
C00747 00123 ∂03-Jan-89 0932 CL-Compiler-mailer Re: Compilation implications
C00750 00124 ∂03-Jan-89 0947 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00754 00125 ∂03-Jan-89 0955 CL-Compiler-mailer Re: environment arguments and compiler contexts and ...
C00757 00126 ∂03-Jan-89 1003 CL-Compiler-mailer Re: Issue COMPILER-DIAGNOSTICS, v7
C00762 00127 ∂03-Jan-89 0959 Common-Lisp-Object-System-mailer Re: Compilation implications
C00766 00128 ∂03-Jan-89 1029 CL-Compiler-mailer issue COMPILED-FUNCTION-REQUIREMENTS, version 1
C00774 00129 ∂03-Jan-89 1153 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 3
C00799 00130 ∂03-Jan-89 1256 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 4
C00809 00131 ∂03-Jan-89 1303 CL-Compiler-mailer issue CONSTANT-COLLAPSING, version 3
C00815 00132 ∂03-Jan-89 1409 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 3
C00819 00133 ∂03-Jan-89 1459 CL-Compiler-mailer issue ALLOW-LOCAL-INLINE
C00821 00134 ∂03-Jan-89 1506 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 3
C00823 00135 ∂03-Jan-89 1516 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
C00825 00136 ∂03-Jan-89 1525 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00828 00137 ∂03-Jan-89 1530 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00830 00138 ∂03-Jan-89 1613 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00833 00139 ∂03-Jan-89 1641 CL-Compiler-mailer issue DEFCONSTANT-SPECIAL
C00837 00140 ∂03-Jan-89 1647 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
C00840 00141 ∂03-Jan-89 1756 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
C00843 00142 ∂03-Jan-89 1838 CL-Compiler-mailer Re: Compilation implications
C00846 00143 ∂03-Jan-89 1908 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
C00850 00144 ∂04-Jan-89 0312 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
C00852 00145 ∂04-Jan-89 0315 CL-Compiler-mailer Re: Issue COMPILER-LET-CONFUSION, v3
C00854 00146 ∂04-Jan-89 0801 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
C00857 00147 ∂04-Jan-89 0828 CL-Compiler-mailer reminder
C00859 00148 ∂04-Jan-89 0944 CL-Compiler-mailer Re: Issue COMPILER-LET-CONFUSION, v3
C00862 00149 ∂04-Jan-89 1106 CL-Compiler-mailer Re: Issue COMPILER-LET-CONFUSION, v3
C00865 00150 ∂04-Jan-89 1125 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
C00868 00151 ∂04-Jan-89 1206 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
C00872 00152 ∂04-Jan-89 1351 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00875 00153 ∂04-Jan-89 1426 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00878 00154 ∂04-Jan-89 1657 CL-Compiler-mailer Issue COMPILER-LET-CONFUSION, v3
C00883 00155 ∂04-Jan-89 1841 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
C00886 00156 ∂04-Jan-89 2017 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
C00889 00157 ∂05-Jan-89 1005 CL-Compiler-mailer Re: Compilation implications
C00900 00158 ∂05-Jan-89 1016 CL-Compiler-mailer Re: Issue COMPILER-DIAGNOSTICS, v7
C00902 00159 ∂05-Jan-89 1228 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00905 00160 ∂05-Jan-89 1235 CL-Compiler-mailer Re: Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, v7
C00910 00161 ∂05-Jan-89 1302 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00914 00162 ∂05-Jan-89 1344 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
C00917 00163 ∂05-Jan-89 1336 Common-Lisp-Object-System-mailer Re: Compilation implications
C00921 00164 ∂05-Jan-89 1342 Common-Lisp-Object-System-mailer Re: Compilation implications
C00925 00165 ∂05-Jan-89 1448 CL-Compiler-mailer Re: issue CONSTANT-COLLAPSING, version 3
C00928 00166 ∂05-Jan-89 1451 CL-Compiler-mailer Re: Compilation implications
C00931 00167 ∂05-Jan-89 1526 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C00939 00168 ∂05-Jan-89 1550 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 3
C00942 00169 ∂05-Jan-89 1547 Common-Lisp-Object-System-mailer Re: Compilation implications
C00948 00170 ∂05-Jan-89 1613 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C00952 00171 ∂05-Jan-89 1721 CL-Compiler-mailer Re: Compilation implications
C00956 00172 ∂05-Jan-89 2051 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00959 00173 ∂06-Jan-89 0749 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00963 00174 ∂06-Jan-89 0934 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00965 00175 ∂06-Jan-89 1231 CL-Compiler-mailer Re: issue COMPILE-ARGUMENT-PROBLEMS
C00970 00176 ∂06-Jan-89 1502 CL-Compiler-mailer Re: issue COMPILE-ENVIRONMENT-CONSISTENCY
C00973 00177 ∂06-Jan-89 1503 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
C00975 00178 ∂06-Jan-89 1502 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
C00978 00179 ∂06-Jan-89 1502 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C00981 00180 ∂06-Jan-89 1504 CL-Compiler-mailer issue LOAD-TIME-EVAL
C00985 00181 ∂06-Jan-89 1528 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00988 00182 ∂06-Jan-89 1535 CL-Compiler-mailer QUOTE and compiled/interpreted consistency
C00993 00183 ∂06-Jan-89 1536 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C00996 00184 ∂06-Jan-89 1520 Common-Lisp-Object-System-mailer Compilation implications
C01006 00185 ∂06-Jan-89 1504 CL-Compiler-mailer Re: issue DEFCONSTANT-SPECIAL
C01008 00186 ∂06-Jan-89 1543 CL-Compiler-mailer Re: issue COMPILE-ENVIRONMENT-CONSISTENCY
C01012 00187 ∂06-Jan-89 1539 Common-Lisp-Object-System-mailer Compilation implications
C01019 00188 ∂06-Jan-89 1556 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
C01023 00189 ∂06-Jan-89 1607 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C01026 00190 ∂06-Jan-89 2109 Common-Lisp-Object-System-mailer Compilation implications
C01032 00191 ∂06-Jan-89 2139 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C01035 00192 ∂06-Jan-89 2207 Common-Lisp-Object-System-mailer Re: Compilation implications
C01039 00193 ∂06-Jan-89 2246 CL-Compiler-mailer Compilation implications
C01044 00194 ∂06-Jan-89 2247 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
C01046 00195 ∂07-Jan-89 0123 CL-Compiler-mailer issue LOAD-TIME-EVAL
C01049 00196 ∂07-Jan-89 1323 CL-Compiler-mailer issue COMPILED-FUNCTION-REQUIREMENTS
C01051 00197 ∂07-Jan-89 1453 CL-Compiler-mailer Re: issue COMPILED-FUNCTION-REQUIREMENTS
C01055 00198 ∂07-Jan-89 1650 CL-Compiler-mailer Re: issue COMPILED-FUNCTION-REQUIREMENTS
C01059 00199 ∂07-Jan-89 2109 CL-Compiler-mailer Re: **DRAFT** Issue COMPILER-VERBOSITY, version 5
C01062 00200 ∂07-Jan-89 2109 CL-Compiler-mailer Re: **DRAFT** Issue COMPILER-DIAGNOSTICS, version 8
C01064 00201 ∂07-Jan-89 2221 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01069 00202 ∂08-Jan-89 1022 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01075 00203 ∂08-Jan-89 1333 CL-Compiler-mailer Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 8
C01080 00204 ∂08-Jan-89 1550 CL-Compiler-mailer Re: Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 8
C01086 00205 ∂08-Jan-89 1738 CL-Compiler-mailer Issue: COMPILER-LET-CONFUSION (Version 4)
C01108 00206 ∂08-Jan-89 1839 CL-Compiler-mailer issue LOAD-TIME-EVAL
C01110 00207 ∂08-Jan-89 2011 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 4)
C01114 00208 ∂08-Jan-89 2329 CL-Compiler-mailer **DRAFT** issue CONSTANT-COLLAPSING
C01117 00209 ∂08-Jan-89 2342 CL-Compiler-mailer **DRAFT** issue CONSTANT-COMPILABLE-TYPES
C01119 00210 ∂09-Jan-89 0644 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
C01120 00211 ∂09-Jan-89 0644 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01124 00212 ∂09-Jan-89 0742 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01128 00213 ∂09-Jan-89 1105 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, version 5
C01154 00214 ∂09-Jan-89 1149 CL-Compiler-mailer Issue DEFINING-MACROS-NON-TOP-LEVEL, v5
C01159 00215 ∂09-Jan-89 1241 CL-Compiler-mailer Re: **DRAFT** issue CONSTANT-COLLAPSING
C01162 00216 ∂09-Jan-89 1321 CL-Compiler-mailer Issue: COMPILER-LET-CONFUSION (Version 6)
C01172 00217 ∂09-Jan-89 1430 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 6)
C01180 00218 ∂09-Jan-89 1453 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 6)
C01183 00219 ∂09-Jan-89 1551 CL-Compiler-mailer Re: issue DEFCONSTANT-SPECIAL
C01186 00220 ∂09-Jan-89 1556 CL-Compiler-mailer Re: Issue COMPILER-DIAGNOSTICS, v7
C01188 00221 ∂09-Jan-89 1601 CL-Compiler-mailer Re: issues relating to compiled constants
C01190 00222 ∂09-Jan-89 1601 CL-Compiler-mailer agenda
C01193 00223 ∂09-Jan-89 1637 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01197 00224 ∂09-Jan-89 1658 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01199 00225 ∂09-Jan-89 1706 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
C01205 00226 ∂09-Jan-89 1713 CL-Compiler-mailer Re: Issue CONSTANT-MODIFICATION, version 2
C01207 00227 ∂09-Jan-89 1746 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 4)
C01210 00228 ∂09-Jan-89 1801 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
C01213 00229 ∂09-Jan-89 1810 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
C01217 00230 ∂09-Jan-89 1824 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
C01225 00231 ∂09-Jan-89 1829 CL-Compiler-mailer Re: Issue CONSTANT-MODIFICATION, version 2
C01228 00232 ∂09-Jan-89 1848 CL-Compiler-mailer **DRAFT** issue QUOTE-MAY-COPY
C01234 00233 ∂09-Jan-89 1902 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
C01237 00234 ∂09-Jan-89 2018 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01240 00235 ∂09-Jan-89 2024 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01242 00236 ∂09-Jan-89 2102 CL-Compiler-mailer Issue: COMPILER-LET-CONFUSION (Version 4)
C01245 00237 ∂09-Jan-89 2135 CL-Compiler-mailer cl-compiler issues online?
C01247 00238 ∂09-Jan-89 2214 CL-Compiler-mailer Issue DEFINING-MACROS-NON-TOP-LEVEL, v5
C01250 00239 ∂09-Jan-89 2304 CL-Compiler-mailer agenda
C01252 00240 ∂10-Jan-89 0005 CL-Compiler-mailer Re: issue DEFCONSTANT-SPECIAL
C01254 00241 ∂10-Jan-89 0054 CL-Compiler-mailer Issue CONSTANT-MODIFICATION, version 2
C01257 00242 ∂10-Jan-89 0109 CL-Compiler-mailer issue LOAD-TIME-EVAL
C01260 00243 ∂10-Jan-89 0127 CL-Compiler-mailer Issue CONSTANT-MODIFICATION, version 2
C01262 00244 ∂10-Jan-89 0404 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION
C01266 00245 ∂10-Jan-89 0520 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01269 00246 ∂10-Jan-89 0752 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01273 00247 ∂10-Jan-89 0755 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C01276 00248 ∂10-Jan-89 0812 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01280 00249 ∂10-Jan-89 1018 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01283 00250 ∂10-Jan-89 1028 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01286 00251 ∂10-Jan-89 1117 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
C01293 00252 ∂10-Jan-89 1125 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01295 00253 ∂10-Jan-89 1145 CL-Compiler-mailer issue MACRO-ENVIRONMENT-EXTENT, version 1
C01303 00254 ∂10-Jan-89 1151 CL-Compiler-mailer issue MACRO-ENVIRONMENT-CREATOR, version 1
C01311 00255 ∂10-Jan-89 1311 CL-Compiler-mailer issue MACRO-ENVIRONMENT-CREATOR, version 1
C01316 00256 ∂10-Jan-89 1347 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-CREATOR, version 1
C01318 00257 ∂10-Jan-89 1406 CL-Compiler-mailer **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
C01322 00258 ∂10-Jan-89 1451 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-CREATOR, version 1
C01325 00259 ∂10-Jan-89 1505 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C01327 00260 ∂10-Jan-89 1519 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
C01332 00261 ∂10-Jan-89 1543 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
C01334 00262 ∂10-Jan-89 1750 CL-Compiler-mailer Re: Issue CONSTANT-MODIFICATION, version 2
C01337 00263 ∂10-Jan-89 1904 Common-Lisp-Object-System-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01347 00264 ∂10-Jan-89 2058 Common-Lisp-Object-System-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01357 00265 ∂10-Jan-89 2240 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
C01367 00266 ∂10-Jan-89 2325 CL-Compiler-mailer **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
C01370 00267 ∂10-Jan-89 2330 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01372 00268 ∂11-Jan-89 0011 CL-Compiler-mailer **DRAFT** issue QUOTE-MAY-COPY
C01375 00269 ∂11-Jan-89 1217 CL-Compiler-mailer **DRAFT** issue QUOTE-MAY-COPY
C01380 00270 ∂11-Jan-89 1421 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01383 00271 ∂11-Jan-89 1421 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01386 00272 ∂11-Jan-89 1421 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01389 00273 ∂11-Jan-89 1421 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities
C01391 00274 ∂11-Jan-89 1427 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
C01393 00275 ∂11-Jan-89 1432 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities
C01396 00276 ∂11-Jan-89 1432 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01399 00277 ∂11-Jan-89 1433 CL-Compiler-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01401 00278 ∂11-Jan-89 1434 CL-Compiler-mailer **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
C01405 00279 ∂11-Jan-89 1438 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
C01408 00280 ∂11-Jan-89 1431 Common-Lisp-Object-System-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01411 00281 ∂11-Jan-89 1431 Common-Lisp-Object-System-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01415 00282 ∂11-Jan-89 1458 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities
C01418 00283 ∂11-Jan-89 1458 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01420 00284 ∂11-Jan-89 1510 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
C01426 00285 ∂11-Jan-89 1515 CL-Compiler-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
C01429 00286 ∂11-Jan-89 1744 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
C01432 00287 ∂11-Jan-89 1805 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION
C01434 00288 ∂11-Jan-89 2040 CL-Compiler-mailer issue MACRO-ENVIRONMENT-CREATOR, version 1
C01436 00289 ∂11-Jan-89 2135 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-CREATOR, version 1
C01439 00290 ∂11-Jan-89 2158 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
C01442 00291 ∂11-Jan-89 2346 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C01445 00292 ∂12-Jan-89 0323 CL-Compiler-mailer **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
C01448 00293 ∂12-Jan-89 0346 CL-Compiler-mailer **DRAFT** issue QUOTE-MAY-COPY
C01452 00294 ∂12-Jan-89 0811 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C01454 00295 ∂12-Jan-89 0852 CL-Compiler-mailer Re: Issue CONSTANT-MODIFICATION, version 2
C01458 00296 ∂12-Jan-89 1037 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 4)
C01460 00297 ∂12-Jan-89 1143 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C01463 00298 ∂12-Jan-89 1201 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C01467 00299 ∂12-Jan-89 1223 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
C01469 00300 ∂13-Jan-89 1340 CL-Compiler-mailer Issue: DEFINING-MACROS-NON-TOP-LEVEL (Version 7)
C01476 00301 ∂13-Jan-89 1454 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 2)
C01496 00302 ∂13-Jan-89 1602 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 2)
C01499 00303 ∂13-Jan-89 1921 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION
C01502 00304 ∂13-Jan-89 1936 CL-Compiler-mailer Re: Issue: LOAD-OBJECTS (Version 2)
C01506 00305 ∂13-Jan-89 1938 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01508 00306 ∂13-Jan-89 1939 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01512 00307 ∂13-Jan-89 1942 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
C01515 00308 ∂13-Jan-89 2058 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 2)
C01523 00309 ∂14-Jan-89 0334 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v8
C01527 00310 ∂20-Jan-89 1259 CL-Compiler-mailer report from Kauai meeting
C01533 00311 ∂20-Jan-89 1333 CL-Compiler-mailer deadlines & priorities
C01538 00312 ∂21-Jan-89 1916 CL-Compiler-mailer issue COMPILER-LET-CONFUSION
C01542 00313 ∂21-Jan-89 1946 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL
C01547 00314 ∂22-Jan-89 1325 CL-Compiler-mailer issue QUOTE-SEMANTICS, version 1
C01560 00315 ∂23-Jan-89 1000 CL-Compiler-mailer Re: deadlines & priorities
C01562 00316 ∂23-Jan-89 1152 CL-Compiler-mailer DEFMETHOD compile-time processing
C01565 00317 ∂23-Jan-89 1153 CL-Compiler-mailer Re: report from Kauai meeting
C01567 00318 ∂23-Jan-89 1155 CL-Compiler-mailer Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
C01570 00319 ∂23-Jan-89 1525 CL-Compiler-mailer Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
C01573 00320 ∂24-Jan-89 0257 CL-Compiler-mailer report from Kauai meeting
C01576 00321 ∂24-Jan-89 0853 CL-Compiler-mailer Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
C01579 00322 ∂24-Jan-89 0928 CL-Compiler-mailer DEFMETHOD compile-time processing
C01586 00323 ∂24-Jan-89 0943 CL-Compiler-mailer issue DEFCONSTANT-SPECIAL, version 4
C01592 00324 ∂24-Jan-89 0944 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 9
C01609 00325 ∂24-Jan-89 0946 CL-Compiler-mailer issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, v9
C01627 00326 ∂24-Jan-89 1255 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01630 00327 ∂24-Jan-89 1300 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01632 00328 ∂24-Jan-89 1313 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01635 00329 ∂24-Jan-89 1330 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01640 00330 ∂24-Jan-89 1335 CL-Compiler-mailer COMPILE-ENVIRONMENT-CONSISTENCY
C01642 00331 ∂24-Jan-89 1415 Common-Lisp-Object-System-mailer DEFMETHOD compile-time processing
C01655 00332 ∂24-Jan-89 1746 CL-Compiler-mailer Re: DEFMETHOD compile-time processing
C01660 00333 ∂24-Jan-89 1812 CL-Compiler-mailer Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
C01664 00334 ∂24-Jan-89 1826 CL-Compiler-mailer Issue: LOAD-TIME-EVAL (Version 8)
C01672 00335 ∂24-Jan-89 1830 CL-Compiler-mailer Issue: COMPILER-VERBOSITY (Version 5)
C01675 00336 ∂24-Jan-89 1834 CL-Compiler-mailer Issue: CONSTANT-CIRCULAR-COMPILATION (Version 5)
C01678 00337 ∂24-Jan-89 1902 CL-Compiler-mailer Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
C01687 00338 ∂24-Jan-89 1912 CL-Compiler-mailer Issue: QUOTE-MAY-COPY (Version 4)
C01693 00339 ∂24-Jan-89 1914 CL-Compiler-mailer Issues: DEFINING-MACROS-NON-TOP-LEVEL, EVAL-WHEN-NON-TOP-LEVEL, COMPILED-FUNCTION-REQUIREMENTS
C01695 00340 ∂24-Jan-89 1940 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C01701 00341 ∂24-Jan-89 1947 CL-Compiler-mailer Re: Issue: COMPILER-VERBOSITY (Version 5)
C01703 00342 ∂24-Jan-89 2049 CL-Compiler-mailer Re: Issue: QUOTE-MAY-COPY (Version 4)
C01709 00343 ∂25-Jan-89 0523 CL-Compiler-mailer Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
C01715 00344 ∂25-Jan-89 0744 CL-Compiler-mailer Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
C01718 00345 ∂25-Jan-89 0818 CL-Compiler-mailer Re: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
C01722 00346 ∂25-Jan-89 0840 CL-Compiler-mailer DEFMETHOD compile-time processing
C01728 00347 ∂25-Jan-89 0900 CL-Compiler-mailer Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
C01735 00348 ∂25-Jan-89 0913 CL-Compiler-mailer Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
C01745 00349 ∂25-Jan-89 0959 CL-Compiler-mailer Re: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
C01750 00350 ∂25-Jan-89 1137 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C01754 00351 ∂25-Jan-89 1247 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C01758 00352 ∂25-Jan-89 1404 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C01762 00353 ∂25-Jan-89 1421 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 9)
C01766 00354 ∂25-Jan-89 1438 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 9)
C01768 00355 ∂25-Jan-89 1621 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 9)
C01770 00356 ∂25-Jan-89 1631 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C01773 00357 ∂25-Jan-89 1646 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C01777 00358 ∂25-Jan-89 1732 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01782 00359 ∂25-Jan-89 1747 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01784 00360 ∂25-Jan-89 1924 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01787 00361 ∂26-Jan-89 0558 CL-Compiler-mailer Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
C01793 00362 ∂26-Jan-89 0711 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01797 00363 ∂26-Jan-89 0835 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
C01801 00364 ∂26-Jan-89 0933 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01806 00365 ∂26-Jan-89 1016 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01810 00366 ∂26-Jan-89 1029 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01813 00367 ∂26-Jan-89 1033 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01815 00368 ∂26-Jan-89 1034 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 9
C01831 00369 ∂26-Jan-89 1039 CL-Compiler-mailer Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
C01833 00370 ∂26-Jan-89 1045 CL-Compiler-mailer issue COMPILER-VERBOSITY, version 6
C01840 00371 ∂26-Jan-89 1225 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01843 00372 ∂26-Jan-89 1258 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01845 00373 ∂26-Jan-89 1653 CL-Compiler-mailer Re: DEFMETHOD compile-time processing
C01853 00374 ∂26-Jan-89 1856 CL-Compiler-mailer Issues: DEFINING-MACROS-NON-TOP-LEVEL, EVAL-WHEN-NON-TOP-LEVEL, COMPILED-FUNCTION-REQUIREMENTS
C01858 00375 ∂27-Jan-89 0244 CL-Compiler-mailer Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
C01861 00376 ∂27-Jan-89 1719 CL-Compiler-mailer Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
C01866 00377 ∂27-Jan-89 1812 CL-Compiler-mailer Re: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
C01870 00378 ∂27-Jan-89 1905 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C01876 00379 ∂27-Jan-89 1913 CL-Compiler-mailer Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
C01882 00380 ∂27-Jan-89 1950 CL-Cleanup-mailer Issue: FUNCTION-NAME (Version 1)
C01907 00381 ∂28-Jan-89 0040 CL-Compiler-mailer re: COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
C01916 00382 ∂28-Jan-89 0858 CL-Compiler-mailer Re: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
C01920 00383 ∂28-Jan-89 0923 CL-Compiler-mailer Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
C01924 00384 ∂29-Jan-89 1427 CL-Compiler-mailer issue IN-PACKAGE-FUNCTIONALITY, version 5
C01931 00385 ∂29-Jan-89 1428 CL-Compiler-mailer Re: issue IN-PACKAGE-FUNCTIONALITY, version 5
C01940 00386 ∂30-Jan-89 0720 CL-Cleanup-mailer Issue: FUNCTION-NAME (Version 1)
C01942 00387 ∂30-Jan-89 0737 CL-Compiler-mailer Re: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
C01945 00388 ∂30-Jan-89 1003 Common-Lisp-Object-System-mailer Issue: FUNCTION-NAME (Version 1)
C01947 00389 ∂30-Jan-89 1241 CL-Compiler-mailer Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
C01955 00390 ∂30-Jan-89 1304 CL-Compiler-mailer Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
C01959 00391 ∂30-Jan-89 1826 CL-Cleanup-mailer issue IN-PACKAGE-FUNCTIONALITY, version 6
C01973 00392 ∂31-Jan-89 0154 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 4
C01978 00393 ∂31-Jan-89 0511 CL-Compiler-mailer Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
C01988 00394 ∂31-Jan-89 0527 CL-Compiler-mailer Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
C01991 00395 ∂31-Jan-89 1226 CL-Editorial-mailer Re: Issue: EXTENSIONS-POSITION (version 1)
C01993 00396 ∂31-Jan-89 1237 CL-Editorial-mailer Re: Issue: EXTENSIONS-POSITION (version 1)
C01996 00397 ∂31-Jan-89 1248 CL-Compiler-mailer Re: Issue: EXTENSIONS-POSITION (version 1)
C01998 00398 ∂31-Jan-89 1300 CL-Editorial-mailer Re: Issue: EXTENSIONS-POSITION (version 1)
C02002 00399 ∂31-Jan-89 1638 CL-Compiler-mailer Issue: MACRO-CACHING (Version 1)
C02019 00400 ∂01-Feb-89 0550 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
C02022 00401 ∂01-Feb-89 1415 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C02026 00402 ∂01-Feb-89 1510 CL-Compiler-mailer issue COMPILE-FILE-SYMBOL-HANDLING, version 1
C02052 00403 ∂01-Feb-89 1554 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C02059 00404 ∂01-Feb-89 1609 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C02062 00405 ∂02-Feb-89 0848 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C02066 00406 ∂02-Feb-89 0908 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
C02071 00407 ∂02-Feb-89 1239 CL-Cleanup-mailer Issue: FUNCTION-NAME (Version 1)
C02083 00408 ∂03-Feb-89 0820 CL-Compiler-mailer Re: Issue: FUNCTION-NAME (Version 1)
C02087 00409 ∂03-Feb-89 0821 CL-Compiler-mailer Issue: LOAD-TIME-EVAL (Version 8)
C02090 00410 ∂03-Feb-89 0949 CL-Compiler-mailer Re: Issue: MACRO-CACHING (Version 1)
C02092 00411 ∂05-Feb-89 2333 CL-Compiler-mailer Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
C02097 00412 ∂06-Feb-89 0836 CL-Compiler-mailer Re: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
C02100 00413 ∂07-Feb-89 1341 Common-Lisp-Object-System-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY
C02102 00414 ∂08-Feb-89 0836 CL-Compiler-mailer Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
C02107 00415 ∂08-Feb-89 0851 CL-Compiler-mailer Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
C02110 00416 ∂08-Feb-89 0912 CL-Compiler-mailer Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
C02115 00417 ∂08-Feb-89 0934 CL-Compiler-mailer Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
C02117 00418 ∂08-Feb-89 0954 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 6
C02128 00419 ∂08-Feb-89 1043 CL-Compiler-mailer issue QUOTE-SEMANTICS, version 1
C02140 00420 ∂09-Feb-89 1126 CL-Compiler-mailer re: COMPILER-LET-CONFUSION, v3
C02143 00421 ∂10-Feb-89 1230 CL-Compiler-mailer issue COMPILED-FUNCTION-REQUIREMENTS, version 3
C02156 00422 ∂10-Feb-89 1257 Common-Lisp-Object-System-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
C02160 00423 ∂10-Feb-89 1326 CL-Compiler-mailer re: EVAL-WHEN-NON-TOP-LEVEL
C02163 00424 ∂10-Feb-89 1443 CL-Compiler-mailer re: EVAL-WHEN-NON-TOP-LEVEL
C02166 00425 ∂10-Feb-89 1449 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
C02171 00426 ∂10-Feb-89 1535 CL-Compiler-mailer Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02201 00427 ∂10-Feb-89 1827 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02207 00428 ∂12-Feb-89 1343 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02217 00429 ∂12-Feb-89 1613 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02222 00430 ∂12-Feb-89 1827 Common-Lisp-Object-System-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
C02225 00431 ∂13-Feb-89 1041 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02232 00432 ∂16-Feb-89 0911 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02236 00433 ∂16-Feb-89 0949 CL-Compiler-mailer pending issues
C02239 00434 ∂16-Feb-89 1016 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02242 00435 ∂16-Feb-89 1019 CL-Compiler-mailer issue COMPILER-LET-CONFUSION
C02245 00436 ∂16-Feb-89 1058 CL-Compiler-mailer issue COMPILER-LET-CONFUSION
C02251 00437 ∂16-Feb-89 1112 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02255 00438 ∂16-Feb-89 1128 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02258 00439 ∂16-Feb-89 1144 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02261 00440 ∂16-Feb-89 1238 CL-Compiler-mailer Re: issue COMPILER-LET-CONFUSION
C02265 00441 ∂16-Feb-89 1330 CL-Compiler-mailer Re: issue COMPILER-LET-CONFUSION
C02269 00442 ∂16-Feb-89 1437 CL-Compiler-mailer Re: issue COMPILER-LET-CONFUSION
C02276 00443 ∂17-Feb-89 1849 CL-Compiler-mailer re: COMPILER-LET-CONFUSION
C02278 00444 ∂18-Feb-89 0759 CL-Compiler-mailer re: COMPILER-LET-CONFUSION
C02280 00445 ∂21-Feb-89 1458 CL-Compiler-mailer Issue COMPILER-LET-CONFUSION
C02282 00446 ∂21-Feb-89 1458 CL-Compiler-mailer Issue WITH-COMPILATION-UNIT
C02285 00447 ∂21-Feb-89 1458 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS, v2
C02291 00448 ∂21-Feb-89 1502 CL-Compiler-mailer Issue CONSTANT-CIRCULAR-COMPILATION, v6
C02292 00449 ∂21-Feb-89 1502 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v5
C02301 00450 ∂21-Feb-89 1501 Common-Lisp-Object-System-mailer Issue MACRO-ENVIRONMENT-EXTENT
C02307 00451 ∂21-Feb-89 1501 Common-Lisp-Object-System-mailer Issue CONSTANT-COMPILABLE-TYPES
C02315 00452 ∂22-Feb-89 1819 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02335 00453 ∂23-Feb-89 0859 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02338 00454 ∂23-Feb-89 0920 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02349 00455 ∂23-Feb-89 1023 CL-Compiler-mailer top-level, eval-when: it's not too late
C02358 00456 ∂23-Feb-89 1229 CL-Compiler-mailer top-level, eval-when: it's not too late
C02360 00457 ∂23-Feb-89 1316 Common-Lisp-Object-System-mailer CLOS defining macros & compilation
C02367 00458 ∂23-Feb-89 1412 CL-Cleanup-mailer Potential issue: MACRO-SPECIAL-FORMS
C02373 00459 ∂23-Feb-89 1446 CL-Compiler-mailer Potential issue: MACRO-SPECIAL-FORMS
C02379 00460 ∂23-Feb-89 1502 CL-Cleanup-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
C02383 00461 ∂23-Feb-89 1523 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02397 00462 ∂23-Feb-89 1525 CL-Compiler-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
C02402 00463 ∂23-Feb-89 1519 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
C02405 00464 ∂23-Feb-89 1532 Common-Lisp-Object-System-mailer CLOS defining macros & compilation
C02408 00465 ∂23-Feb-89 1546 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
C02411 00466 ∂23-Feb-89 1550 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
C02414 00467 ∂23-Feb-89 1558 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
C02418 00468 ∂23-Feb-89 1607 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
C02422 00469 ∂23-Feb-89 1646 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02432 00470 ∂23-Feb-89 1650 CL-Compiler-mailer remote environments
C02439 00471 ∂23-Feb-89 1704 CL-Compiler-mailer Re: CLOS defining macros & compilation
C02442 00472 ∂23-Feb-89 1746 CL-Compiler-mailer Re: remote environments
C02448 00473 ∂23-Feb-89 1834 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02456 00474 ∂23-Feb-89 1849 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02460 00475 ∂23-Feb-89 2103 Common-Lisp-Object-System-mailer CLOS defining macros & compilation
C02465 00476 ∂23-Feb-89 2236 CL-Compiler-mailer re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02470 00477 ∂23-Feb-89 2355 CL-Compiler-mailer re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02487 00478 ∂24-Feb-89 0158 CL-Compiler-mailer Symbols in compiled files, and Issues IN-PACKAGE-FUNCTIONALITY & CONSTANT-COMPILABLE-TYPES
C02492 00479 ∂24-Feb-89 0157 Common-Lisp-Object-System-mailer Issue CONSTANT-COMPILABLE-TYPES
C02496 00480 ∂24-Feb-89 0754 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
C02501 00481 ∂24-Feb-89 0805 CL-Compiler-mailer re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02514 00482 ∂24-Feb-89 1005 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02523 00483 ∂24-Feb-89 1112 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02531 00484 ∂24-Feb-89 1533 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02547 00485 ∂27-Feb-89 0854 CL-Compiler-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY
C02551 00486 ∂27-Feb-89 0938 CL-Cleanup-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
C02558 00487 ∂28-Feb-89 1340 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02566 00488 ∂28-Feb-89 1344 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02569 00489 ∂28-Feb-89 1348 CL-Compiler-mailer remote environments
C02571 00490 ∂28-Feb-89 1347 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL
C02574 00491 ∂28-Feb-89 1350 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02576 00492 ∂28-Feb-89 1429 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02580 00493 ∂28-Feb-89 1555 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02582 00494 ∂28-Feb-89 1635 CL-Compiler-mailer Re: remote environments
C02584 00495 ∂28-Feb-89 1634 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02587 00496 ∂28-Feb-89 1704 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL
C02590 00497 ∂01-Mar-89 1030 CL-Compiler-mailer Re: Issue WITH-COMPILATION-UNIT
C02593 00498 ∂02-Mar-89 1037 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 10
C02619 00499 ∂03-Mar-89 0841 CL-Compiler-mailer Re: Issue LOAD-TIME-EVAL (shouldn't this be called issue
C02622 00500 ∂05-Mar-89 1604 CL-Compiler-mailer deadlines
C02624 00501 ∂05-Mar-89 1653 CL-Compiler-mailer subcommittee meeting
C02626 00502 ∂05-Mar-89 1742 CL-Compiler-mailer issue CONSTANT-COMPILABLE-TYPES, version 7
C02658 00503 ∂05-Mar-89 1819 CL-Compiler-mailer subcommittee meeting
C02660 00504 ∂05-Mar-89 1837 CL-Compiler-mailer Re: subcommittee meeting
C02662 00505 ∂05-Mar-89 1917 CL-Compiler-mailer cl-compiler issue status, as of 3/5
C02666 00506 ∂06-Mar-89 1622 CL-Compiler-mailer Re: COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE
C02670 00507 ∂06-Mar-89 1711 CL-Compiler-mailer Re: COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE
C02673 00508 ∂06-Mar-89 1711 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 10
C02675 00509 ∂06-Mar-89 1812 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02682 00510 ∂06-Mar-89 1840 Common-Lisp-Object-System-mailer remote environments
C02696 00511 ∂06-Mar-89 2146 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02700 00512 ∂06-Mar-89 2243 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
C02704 00513 ∂06-Mar-89 2354 CL-Compiler-mailer Issue: SAFE-CODE (Version 1)
C02710 00514 ∂07-Mar-89 0727 CL-Compiler-mailer Re: Issue: SAFE-CODE (Version 1)
C02712 00515 ∂07-Mar-89 0808 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02716 00516 ∂07-Mar-89 0828 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL
C02719 00517 ∂07-Mar-89 0912 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02726 00518 ∂07-Mar-89 0924 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02729 00519 ∂07-Mar-89 0932 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02732 00520 ∂07-Mar-89 0942 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02734 00521 ∂07-Mar-89 1101 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02741 00522 ∂07-Mar-89 1140 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02744 00523 ∂07-Mar-89 1418 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02749 00524 ∂07-Mar-89 1423 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02754 00525 ∂07-Mar-89 1458 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02759 00526 ∂07-Mar-89 1546 Common-Lisp-Object-System-mailer Re: remote environments
C02762 00527 ∂07-Mar-89 1744 CL-Compiler-mailer A (new) (old) definition of "top-level"
C02769 00528 ∂07-Mar-89 1825 CL-Compiler-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
C02774 00529 ∂08-Mar-89 1145 CL-Compiler-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
C02790 00530 ∂08-Mar-89 1401 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, version 6
C02812 00531 ∂08-Mar-89 1416 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, version 6
C02814 00532 ∂08-Mar-89 1708 CL-Compiler-mailer A (new) (old) definition of "top-level"
C02820 00533 ∂08-Mar-89 1719 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
C02825 00534 ∂09-Mar-89 0832 CL-Compiler-mailer Re: issue COMPILER-LET-CONFUSION, version 6
C02837 00535 ∂09-Mar-89 1102 CL-Compiler-mailer Issue MACRO-ENVIRONMENT-EXTENT
C02841 00536 ∂09-Mar-89 1301 Common-Lisp-Object-System-mailer Re: Issue: LOAD-OBJECTS (Version 2)
C02846 00537 ∂09-Mar-89 1334 CL-Cleanup-mailer issue IN-PACKAGE-FUNCTIONALITY, version 6
C02848 00538 ∂09-Mar-89 1329 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 3)
C02871 00539 ∂09-Mar-89 1325 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 2)
C02875 00540 ∂09-Mar-89 1421 CL-Compiler-mailer issue MACRO-ENVIRONMENT-EXTENT, version 2
C02889 00541 ∂09-Mar-89 1539 CL-Compiler-mailer Issue: LOCALLY-TOP-LEVEL (Version 1)
C02897 00542 ∂09-Mar-89 1603 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 6
C02898 00543 ∂09-Mar-89 1609 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 8
C02908 00544 ∂09-Mar-89 1619 Common-Lisp-Object-System-mailer issue CLOS-MACRO-COMPILATION
C02910 00545 ∂09-Mar-89 1606 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 6
C02943 00546 ∂09-Mar-89 1652 CL-Compiler-mailer cl-compiler issue status as of 3/9
C02947 00547 ∂09-Mar-89 1708 CL-Compiler-mailer issue CLOS-MACRO-COMPILATION
C02950 00548 ∂09-Mar-89 1920 CL-Cleanup-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
C02952 00549 ∂09-Mar-89 2220 CL-Compiler-mailer issue MACRO-ENVIRONMENT-EXTENT, version 2
C02955 00550 ∂09-Mar-89 2315 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02985 00551 ∂10-Mar-89 0626 CL-Compiler-mailer Re: Issue: LOCALLY-TOP-LEVEL (Version 1)
C02987 00552 ∂10-Mar-89 0836 CL-Compiler-mailer Re: Issue: LOCALLY-TOP-LEVEL (Version 1)
C02989 00553 ∂10-Mar-89 0834 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
C02997 00554 ∂10-Mar-89 0916 CL-Cleanup-mailer issue IN-PACKAGE-FUNCTIONALITY, version 7
C03007 00555 ∂10-Mar-89 1000 CL-Cleanup-mailer issue IN-PACKAGE-FUNCTIONALITY, version 7
C03009 00556 ∂10-Mar-89 1258 Common-Lisp-Object-System-mailer issue CLOS-MACRO-COMPILATION, version 1
C03019 00557 ∂10-Mar-89 1324 CL-Compiler-mailer Issue: DEFINE-OPTIMIZER (Version 2)
C03035 00558 ∂10-Mar-89 1407 CL-Compiler-mailer Issue: WITH-COMPILATION-UNIT (Version 2)
C03044 00559 ∂10-Mar-89 1525 CL-Compiler-mailer Re: Issue: DEFINE-OPTIMIZER (Version 2)
C03047 00560 ∂10-Mar-89 1556 CL-Compiler-mailer Re: Issue: WITH-COMPILATION-UNIT (Version 2)
C03050 00561 ∂10-Mar-89 1553 CL-Cleanup-mailer Re: issue IN-PACKAGE-FUNCTIONALITY, version 7
C03052 00562 ∂10-Mar-89 1615 CL-Compiler-mailer Re: Issue: WITH-COMPILATION-UNIT (Version 2)
C03055 00563 ∂10-Mar-89 1730 CL-Compiler-mailer issue DEFINE-OPTIMIZER, version 3
C03071 00564 ∂11-Mar-89 0126 Common-Lisp-Object-System-mailer Re: issue CLOS-MACRO-COMPILATION, version 1
C03075 00565 ∂11-Mar-89 0152 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
C03083 00566 ∂11-Mar-89 0200 CL-Compiler-mailer Re: Issue: DEFINE-OPTIMIZER (Version 2)
C03087 00567 ∂11-Mar-89 0150 Common-Lisp-Object-System-mailer Re: Issue MACRO-ENVIRONMENT-EXTENT
C03091 00568 ∂11-Mar-89 0810 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
C03097 00569 ∂11-Mar-89 0818 Common-Lisp-Object-System-mailer Re: issue CLOS-MACRO-COMPILATION, version 1
C03102 00570 ∂11-Mar-89 1220 Common-Lisp-Object-System-mailer Re: issue CLOS-MACRO-COMPILATION, version 1
C03106 00571 ∂11-Mar-89 1243 CL-Compiler-mailer issue PROCLAIM-ETC-IN-COMPILE-FILE, version 3
C03117 00572 ∂11-Mar-89 1304 CL-Compiler-mailer Issue: DEFINE-OPTIMIZER (Version 4)
C03139 00573 ∂11-Mar-89 1321 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
C03147 00574 ∂11-Mar-89 1502 CL-Compiler-mailer Re: issue CLOS-MACRO-COMPILATION, version 1
C03152 00575 ∂11-Mar-89 1531 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
C03156 00576 ∂11-Mar-89 1621 CL-Compiler-mailer Issue CONSTANT-COMPILABLE-TYPES, version 7
C03159 00577 ∂11-Mar-89 1643 CL-Compiler-mailer Issue CLOS-MACRO-COMPILATION, version 1
C03164 00578 ∂11-Mar-89 1658 Common-Lisp-Object-System-mailer Issue: LOAD-OBJECTS (Version 3)
C03172 00579 ∂11-Mar-89 1718 CL-Compiler-mailer Re: Issue CONSTANT-COMPILABLE-TYPES, version 7
C03177 00580 ∂11-Mar-89 1745 Common-Lisp-Object-System-mailer Re: Issue: LOAD-OBJECTS (Version 3)
C03180 00581 ∂11-Mar-89 1806 CL-Compiler-mailer Re: Issue CONSTANT-COMPILABLE-TYPES, version 7
C03184 00582 ∂12-Mar-89 1002 CL-Compiler-mailer issue SYNTACTIC-ENVIRONMENT-ACCESS, version 4
C03214 00583 ∂12-Mar-89 1022 CL-Compiler-mailer Issue CONSTANT-COMPILABLE-TYPES, version 7
C03217 00584 ∂12-Mar-89 1031 CL-Compiler-mailer Issue CONSTANT-COMPILABLE-TYPES, version 7
C03220 00585 ∂12-Mar-89 1032 Common-Lisp-Object-System-mailer Issue: LOAD-OBJECTS (Version 3)
C03222 00586 ∂12-Mar-89 1045 CL-Compiler-mailer Re: Issue CONSTANT-COMPILABLE-TYPES, version 7
C03225 00587 ∂12-Mar-89 1111 CL-Compiler-mailer Issue CONSTANT-COMPILABLE-TYPES, version 7
C03228 00588 ∂12-Mar-89 2014 Common-Lisp-Object-System-mailer Re: remote environments
C03240 00589 ∂13-Mar-89 0653 Common-Lisp-Object-System-mailer Re: remote environments
C03246 00590 ∂13-Mar-89 0853 X3J13-mailer issue COMPILER-VERBOSITY, version 6
C03248 00591 ∂13-Mar-89 1023 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
C03253 ENDMK
C⊗;
∂12-Dec-88 0756 CL-Compiler-mailer Re: Objects in quoted constants
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 12 Dec 88 07:54:15 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04752; 12 Dec 88 15:36 GMT
Date: Mon, 12 Dec 88 15:43:59 GMT
Message-Id: <3897.8812121543@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Objects in quoted constants
To: Jon L White <@sail.stanford.edu:jonl@lucid.com>
In-Reply-To: Jon L White's message of Sat, 10 Dec 88 05:27:56 PST
Cc: cl-compiler@sail.stanford.edu, cperdue@sun.com
> Uh, that is still one form, the PROGN form. There is no state saved
> between one call to PRINT and another (as would be necessary to do
> #= type printing in a compile-file situation.)
I don't want to beat this issue to death, but KCL's COMPILE-FILE
happens to print all the data using PRINT, and I think it uses
one call to PRINT. True, there are some problems...
I think it be a shame if source->source processors for CL couldn't
be written (in CL) using READ and PRINT. It may be that READ and
PRINT will never be fully capable because of the scope issue, but
I still think that READ and PRINT should be able to handle as much
detail about data structures as other methods can.
I wanted to write a preprocessor a while ago. What I ended up
doing was to copy the Lisp source as text but with "(PREPROCESS"
[not the actual name] as an extra line at the front and ")" as an
extra line at the end. I would have preferred a different
solution.
-- Jeff
∂12-Dec-88 1159 CL-Compiler-mailer issue CONSTANT-MODIFICATION, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Dec 88 11:59:16 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA19913; Mon, 12 Dec 88 12:57:41 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03230; Mon, 12 Dec 88 12:57:38 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812121957.AA03230@defun.utah.edu>
Date: Mon, 12 Dec 88 12:57:37 MST
Subject: issue CONSTANT-MODIFICATION, version 2
To: cl-compiler@sail.stanford.edu
I've removed the part of this proposal that deals with allowing constants
to be copied to read-only memory, since that is now being dealt with in
issue QUOTE-MAY-COPY. I hope that what is left is non-controversial.
Issue: CONSTANT-MODIFICATION
References: CLtL p. 78, 87
Issue CONSTANT-COLLAPSING
Category: CLARIFICATION
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 12 Dec 1988, Sandra Loosemore
Problem Description:
CLtL states that an implementation is permitted to "collapse"
constants appearing in code to be compiled if they are EQUAL. This
implicit sharing of compiled data structures may result in
unpredictable behavior if destructive operations are performed.
However, CLtL does not explicitly allow or disallow destructive
operations on constants.
Proposal CONSTANT-MODIFICATION:DISALLOW:
Clarify that it is an error to destructively modify objects which are
self-evaluating forms or which appear inside of a QUOTE special form.
Rationale:
Disallowing modification of constants consistently in all situations,
rather than just in compiled code, is proposed because in some
compiled-only situations it may be difficult to distinguish between
"compiled" and "interpreted" code.
Current Practice:
Many implementations "collapse" compiled constants.
Many implementations treat compiled constants as read-only. In
PSL/PCLS, for example, quoted data structures in compiled code are
copied into a part of memory that is not scanned by the garbage
collector. The TI Explorer's loader also copies constants into a
write-protected memory area.
Cost to implementors:
None.
Cost to users:
User programs which perform destructive operations on constants are
already nonportable.
Benefits:
Many novice programmers do not realize that modifying quoted data
structures is an error in many implementations. Including an explicit
statement in the standard that doing so is a bad idea will reduce
confusion.
Discussion:
The issue of whether implementations are permitted to copy constants
seen by EVAL or COMPILE is discussed separately as issue QUOTE-MAY-COPY.
-------
∂12-Dec-88 1212 CL-Compiler-mailer issue CONSTANT-COLLAPSING, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Dec 88 12:12:08 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA20541; Mon, 12 Dec 88 13:11:14 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03239; Mon, 12 Dec 88 13:11:11 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812122011.AA03239@defun.utah.edu>
Date: Mon, 12 Dec 88 13:11:08 MST
Subject: issue CONSTANT-COLLAPSING, version 2
To: cl-compiler@sail.stanford.edu
The change on this one is to make coalescing use the same rules as
CONSTANT-COMPILABLE-TYPES.
Issue: CONSTANT-COLLAPSING
References: CLtL p. 78, 87
Issue CONSTANT-MODIFICATION
Issue CONSTANT-COMPILABLE-TYPES
Issue EQUAL-STRUCTURE
Category: CHANGE
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 12 Dec 1988, Sandra Loosemore
Problem Description:
CLtL states that an implementation is permitted to "collapse" or
coalesce constants appearing in code to be compiled if they are EQUAL.
The definition of EQUAL does not permit coalescing of more general
isomorphic data structures (such as arrays and structures), which is
often desirable.
Proposal CONSTANT-COLLAPSING:GENERALIZE:
State the an implementation is permitted to "collapse" constants
appearing in code to be compiled if they are equivalent under the
relationship specified in issue CONSTANT-COMPILABLE-TYPES.
Rationale:
There is little reason why implementations should not be allowed to
perform more general collapsing of structures, since the arguments
against doing so also apply to collapsing of EQUAL structures, which
is already permitted.
Current Practice:
Both PSL/PCLS and A-Lisp collapse isomorphic arrays and structures,
and certain other data types that are defined internally as structures
(RANDOM-STATEs, for example). Lucid Common Lisp also uses a more
general coalescing predicate than EQUAL.
Cost to implementors:
None. This extends the range of permitted behavior for
implementations but does not require any implementation to change.
Cost to users:
It is hard to imagine a program that would break under this proposal.
The EQL-ness or uniqueness of composite structures in compiled code
cannot be guaranteed in any event, since the combination of
COMPILE-FILE and LOAD generally results in a copy of the original
structure.
Benefits:
Collapsing of isomorphic arrays and structures may lead to significant
memory savings in some applications.
Discussion:
Some people believe that if the definition of EQUAL weren't "broken",
there wouldn't be any need for this proposal.
There is no inherent reason why the "coalescing predicate" must be the
same as the relationship used by the compiler/loader to construct
equivalent copies of objects of constants, but making the same rules
be applied in both situations simplifies the language somewhat.
-------
∂12-Dec-88 1327 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Dec 88 13:27:24 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA23461; Mon, 12 Dec 88 14:26:23 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03256; Mon, 12 Dec 88 14:26:17 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812122126.AA03256@defun.utah.edu>
Date: Mon, 12 Dec 88 14:26:16 MST
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 3
To: cl-compiler@sail.stanford.edu
I have merged versions 1 and 2 (which was labeled version 1), and
attempted to summarize the discussion. We seem divided on this issue
so I think it would be reasonable to present both alternatives to the
full committee. There are other possibilities as well -- for example,
we could require the compiler to support sharing but not circularity
(which would help with the uninterned symbol problem already noted for
issue CONSTANT-COMPILABLE-TYPES) , say "signals an error" instead of
"is an error", and the like. Let me know if you have suggestions.
Issue: CONSTANT-CIRCULAR-COMPILATION
References: Issue CONSTANT-COLLAPSING
Issue QUOTE-MAY-COPY
Category: CLARIFICATION, ADDITION
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 14 Nov 1988, Cris Perdue
V3, 12 Dec 1988, Sandra Loosemore (merge versions 1 and 2)
Problem Description:
CLtL does not specify whether constants containing circular or
recursive references may be compiled, or whether the compiler must
preserve sharing of EQ substructures.
The proposals below apply to COMPILE-FILE, since it must inherently
copy structures. If issue QUOTE-MAY-COPY is resolved in favor of
allowing COMPILE and possibly EVAL to copy structures, the same
constraints would also apply in those situations.
Proposal CONSTANT-CIRCULAR-COMPILATION:NO
State that it is an error for an object containing a circular reference to
appear as a constant to be compiled. State that the compiler is not
required to preserve EQness of substructures.
Rationale:
This proposal would not require any existing implementation to change.
Disallowing portable programs from containing circular constants
allows compiled file loaders to use somewhat simpler implementation
strategies (for example, to build constants in a strict bottom-up
fashion).
Proposal: CONSTANT-CIRCULAR-COMPILATION:FLAG
Add to the definition of Common Lisp a special variable:
*DUMP-CIRCLE* [Special variable]
State that if the (compile-time) value of *DUMP-CIRCLE* is NIL, it is
an error for an object containing a circular reference to appear as a
constant to be compiled. State that the compiler is not required to
preserve EQness of substructures.
The initial value of *DUMP-CIRCLE* is implementation-dependent.
Rationale:
As with *PRINT-CIRCLE* for printing, writing representations of
objects to a stream is much faster if the implementation does not
attempt to support circular, self-recursive, mutually-referential,
etc. substructure.
*PRINT-CIRCLE* is also not required to detect EQness of substructures.
Current Practice:
A-Lisp preserves EQness of substructures (since it makes an effort to
collapse isomorphic structures) but signals an error if an attempt is
made to compile a circular constant. PSL and Utah Common Lisp both
get stuck in an infinite loop if an attempt is made to compile a
reentrant structure. The TI Explorer compiler is able to reproduce
recursive lists and arrays, but currently hangs in a loop on a
circular list. Lucid and Symbolics can handle circular constants
correctly. Franz uses a flag to control whether or not to attempt to
detect circular constants.
Cost to implementors:
We know of no implementation that would have to change under proposal
NO. For proposal FLAG, some implementations would require sweeping
changes; in some cases a completely different dumper/loader strategy
would have to be implemented.
Cost to users:
The situation now is that programs which depend upon circularity or
sharing of substructure being preserved by the compiler are already
nonportable. Proposal NO simply formalizes the status quo. Proposal
FLAG would offer users functionality that is currently not portable.
Benefits:
An area of ambiguity in the language is removed.
Discussion:
JonL has argued against proposal CONSTANT-CIRCULAR-COMPILATION:NO, saying
I don't see any performance justification; and even if there were, I'd
look at it with a very jaundiced eye, favoring interpreter/compiler
consistency over nickle-and-dime issues of compiler speed.
Loosemore supports issue CONSTANT-CIRCULAR-COMPILATION:NO because it
is the most consistent with current practice -- no implementations
would be required to change and no currently portable programs would
be invalidated. While one could make an argument for this proposal on
the basis of improving compiler speed, the compatibility issue is seen
as far more important.
There was also quite a bit of discussion about how this proposal
relates to the requirement in CLtL (p. 69) about preserving the
EQLness of references to symbolic constants. There is less reason for
not requiring shared references in ordinary quoted constants to be
preserved than for disallowing circularity, but we would have to
define the scope over which such sharing would have to be detected.
-------
∂12-Dec-88 1344 CL-Compiler-mailer issue status, 12/12/88
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Dec 88 13:44:42 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA24175; Mon, 12 Dec 88 14:43:08 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03268; Mon, 12 Dec 88 14:43:05 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812122143.AA03268@defun.utah.edu>
Date: Mon, 12 Dec 88 14:43:03 MST
Subject: issue status, 12/12/88
To: cl-compiler@sail.stanford.edu
Here is the summary of the status of our pending issues as of today.
Once again I must ask you to note that we are running out of time
before the January meeting. My effective deadline is the middle of
next week, because that's when I'm going on vacation.
These issues appear to be ready for release.
ALLOW-LOCAL-INLINE
COMPILE-ENVIRONMENT-CONSISTENCY
COMPILER-LET-CONFUSION
DEFCONSTANT-SPECIAL
LOAD-TIME-EVAL
SHARP-COMMA-CONFUSION
The following issues are those that I would like to finish up within the
next week or so, with notes on what remains to be done.
COMPILER-DIAGNOSTICS
The NOTICE condition type hasn't happened yet. I was going to change
references to the NOTICE condition to the STYLE-WARNING condition,
which is a subtype of warning (allowing user condition handlers to use
the MUFFLE-WARNING restart on it to suppress the messages). Any
objections?
COMPILER-VERBOSITY
Pierson indicated he wanted to submit an alternate proposal on this
issue, but hasn't done so. Can/should we go ahead with the current
proposal?
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
I've been working on a revised version that is essentially complete
except for information about the CLOS defining macros. The CLOS
people haven't responded to my requests for help. I don't hear from
them, should we release the issue anyway, leaving the CLOS macros for
later?
DEFINING-MACROS-NON-TOP-LEVEL
EVAL-WHEN-NON-TOP-LEVEL
There's been a suggestion that defining macros should only cause
compile-time side effects at top level, and that (EVAL-WHEN
(COMPILE)...) should be a no-op except at top level. Is this
agreeable to everybody?
QUOTE-MAY-COPY
Do we really need all three options in the latest writeup?
CONSTANT-COMPILABLE-TYPES
We need a new draft of this proposal to incorporate the latest
round of discussion. Cris???
CONSTANT-CIRCULAR-COMPILATION
CONSTANT-COLLAPSING
CONSTANT-MODIFICATION
If nobody has complaints about the latest writeups, I'll move these
into the "ready for release" category.
The following issues are those which I don't plan to work on myself
until after the January meeting:
CONSTANT-ARRAY-ATTRIBUTES
Subsumed by CONSTANT-COMPILABLE-TYPES?
COMPILE-FILE-ENVIRONMENT
Superseded by issue SYNTACTIC-ENVIRONMENT-ACCESS, unless that issue
has died.
DEFCONSTANT-NOT-WIRED
Still under discussion, no consensus yet
DEFCONSTANT-VALUE
Subsumed by issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
DEFINE-OPTIMIZER
Waiting for revisions (Pitman)
FILE-COMPILATION
same issue as CONSTANT-COMPILABLE-TYPES
PROCLAIM-ETC-IN-COMPILE-FILE
Waiting for resolution of related cleanup issues (DEFPACKAGE,
IN-PACKAGE-FUNCTIONALITY)
SYNTACTIC-ENVIRONMENT-ACCESS
Waiting for new writeup (Benson)
WITH-COMPILATION-UNIT
Waiting for revisions to existing proposal (Pitman)
-------
∂12-Dec-88 1425 CL-Compiler-mailer Re: issue CONSTANT-COLLAPSING, version 2
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 12 Dec 88 14:24:59 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA00935; Mon, 12 Dec 88 17:23:57 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA11107; Mon, 12 Dec 88 17:24:06 EST
Message-Id: <8812122224.AA11107@mist.>
To: "sandra%defun@cs.utah.edu"@Multimax.encore.com (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue CONSTANT-COLLAPSING, version 2
In-Reply-To: Your message of Mon, 12 Dec 88 13:11:08 -0700.
<8812122011.AA03239@defun.utah.edu>
Date: Mon, 12 Dec 88 17:24:03 EST
From: Dan L. Pierson <pierson@mist.encore.com>
I support this proposal.
∂12-Dec-88 1434 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 3
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 12 Dec 88 14:30:12 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA01011; Mon, 12 Dec 88 17:29:07 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA11122; Mon, 12 Dec 88 17:29:17 EST
Message-Id: <8812122229.AA11122@mist.>
To: "sandra%defun@cs.utah.edu"@multimax.encore.com (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 3
In-Reply-To: Your message of Mon, 12 Dec 88 14:26:16 -0700.
<8812122126.AA03256@defun.utah.edu>
Date: Mon, 12 Dec 88 17:29:15 EST
From: Dan L. Pierson <pierson@mist.encore.com>
I'd prefer to see a global replace of "compiler" ==> "file compiler".
However I admit that the caveat in the Problem Description does cover
this if you read it carefully enough.
Other than that, I'm inclined to support FLAG. Once again it's
supporting possibly broken current practice versus maintaining the
traditional flexibility of Lisp. On the other hand, this doesn't
sound likely to be important to many people so it would take a few
good existence proofs to firm up my support.
∂12-Dec-88 1434 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 12 Dec 88 14:29:16 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA01001; Mon, 12 Dec 88 17:28:08 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA10985; Mon, 12 Dec 88 15:48:47 EST
Message-Id: <8812122048.AA10985@mist.>
To: "sandra%defun@cs.utah.edu"@multimax.encore.com (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue QUOTE-MAY-COPY, version 2
In-Reply-To: Your message of Sat, 10 Dec 88 12:12:08 -0700.
<8812101912.AA02084@defun.utah.edu>
Date: Mon, 12 Dec 88 15:48:45 EST
From: Dan L. Pierson <pierson@mist.encore.com>
I also support QUOTE-MAY-COPY:NOT-EVAL-OR-COMPILE. In the absence of
overwhelming opposing reasons, we should not diminish traditional Lisp
functionality. While NOT-EVAL may be more in line with current
practice of a couple of implementations, the argument that these
implementations are already broken is at least as strong as the
argument that we shouldn't break them by pointing out that they don't
conform to the language standard.
However, my position on this is not unalterable. I would like to see
a writeup with more discussion that fairly presents both views. As
with so many of the compiler issues, this one has gotten buried in
such a torrent of mail that I can't keep track of all the arguments.
One of the global disagreements seems to be that some members of the
committee want to optimize file compilation at the expense of
incremental compilation. Others, including myself, see incremental
compilation as a very important tool that is potentially key to the
success of large, stock hardware AI applications. Many Lisp
applications write new code as they go along. It is reasonable and
desireable for those applications to compile such code when they
expect it to be executed frequently. It is also reasonable for them
to expect such code to share data structures with other code no matter
what order the data structures and code fragments were created in.
Maybe JonL's recent proposal that QUOTE can copy at most once (i.e.
that all references to (QUOTE FOO) must be EQL to each other even
though they may not be EQL to FOO) satisfies, or sufficiently
minimizes, the above objections, but I'm not sure.
∂12-Dec-88 1454 CL-Compiler-mailer Re: issue status, 12/12/88
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 12 Dec 88 14:53:37 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA01207; Mon, 12 Dec 88 17:52:23 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA11172; Mon, 12 Dec 88 17:52:31 EST
Message-Id: <8812122252.AA11172@mist.>
To: "sandra%defun@cs.utah.edu"@Multimax.encore.com (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue status, 12/12/88
Date: Mon, 12 Dec 88 17:52:29 EST
From: Dan L. Pierson <pierson@mist.encore.com>
COMPILER-DIAGNOSTICS
The NOTICE condition type hasn't happened yet. I was going to change
references to the NOTICE condition to the STYLE-WARNING condition,
which is a subtype of warning (allowing user condition handlers to use
the MUFFLE-WARNING restart on it to suppress the messages). Any
objections?
The NOTICE condition type is created by this proposal. There is no
need for any other action. I object to its removal on the grounds
that a separate issue to create it hasn't been passed in some other
place (are you thinking of Cleanup?).
COMPILER-VERBOSITY
Pierson indicated he wanted to submit an alternate proposal on this
issue, but hasn't done so. Can/should we go ahead with the current
proposal?
A new (two proposal, sigh) version will immediately follow this reply.
DEFINING-MACROS-NON-TOP-LEVEL
EVAL-WHEN-NON-TOP-LEVEL
There's been a suggestion that defining macros should only cause
compile-time side effects at top level, and that (EVAL-WHEN
(COMPILE)...) should be a no-op except at top level. Is this
agreeable to everybody?
I have no objections.
QUOTE-MAY-COPY
Do we really need all three options in the latest writeup?
ALWAYS and NOT-EVAL (:-)) can go away as far as I'm concerned.
FILE-COMPILATION
same issue as CONSTANT-COMPILABLE-TYPES
I don't agree that this is just the same as CONSTANT-COMPILABLE-TYPES.
While I don't necessarily support FILE-COMPILATION as it stands, I do
support Kent and Jeff's belief that we need to simplify some of these
issues, provide some sort of unifying framework, and not sacrifice the
traditional strengths of Lisp to support simple file-compilation-only
implementations.
∂12-Dec-88 1456 CL-Compiler-mailer Issue: COMPILER-VERBOSITY (Version 2)
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 12 Dec 88 14:55:50 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA01268; Mon, 12 Dec 88 17:54:39 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA11186; Mon, 12 Dec 88 17:54:46 EST
Message-Id: <8812122254.AA11186@mist.>
To: cl-compiler@sail.stanford.edu
Subject: Issue: COMPILER-VERBOSITY (Version 2)
Date: Mon, 12 Dec 88 17:54:44 EST
From: Dan L. Pierson <pierson@mist.encore.com>
Issue: COMPILER-VERBOSITY
References: CLtL p. 438-329; 426
issue COMPILER-DIAGNOSTICS
Category: CHANGE/CLARIFICATION/ENHANCEMENT
Edit History: V1, 25 Oct 1988, Sandra Loosemore
V2, 12 Dec 1988, Dan L. Pierson (add USE-CONDITIONS)
Problem Description:
Implementations vary widely in the amount of information that is printed
out by COMPILE-FILE. In some situations, it would be useful to control
how much information is printed.
Proposal COMPILER-VERBOSITY:LIKE-LOAD:
Introduce a special variable, *COMPILE-VERBOSE*, with an implementation-
dependent initial value.
Add :VERBOSE and :PRINT keyword arguments to the function COMPILE-FILE,
analogous to those for the function LOAD.
The :VERBOSE argument (which defaults to the value of *COMPILE-VERBOSE*),
if true, permits COMPILE-FILE to print a message in the form of a comment
to *STANDARD-OUTPUT* indicating what file is being compiled and other
useful information.
The :PRINT argument (which defaults to NIL), if true, causes
information about top-level forms in the file being compiled to be
printed to *STANDARD-OUTPUT*. Exactly what is printed will vary from
implementation to implementation, but nevertheless some information
will be printed.
Rationale:
This proposal makes COMPILE-FILE behave like LOAD. There is already
some precedent for doing this (for example, issue COMPILE-FILE-PACKAGE,
which makes COMPILE-FILE as well as LOAD rebind *PACKAGE*).
Current Practice:
Lucid provides a :MESSAGES keyword argument to COMPILE-FILE, which can
either be a stream to send progress messages to, or NIL to suppress messages.
The default value is T, which sends messages to "the standard terminal
device".
On the TI Explorer, COMPILE-FILE displays the name of the function being
compiled when the option :VERBOSE T is given or special variable
COMPILER:COMPILER-VERBOSE is true. (In other words, they use :VERBOSE
to mean what this proposal says to use :PRINT for.)
Cost to implementors:
This is an incompatible change for some implementations, but the changes
required should be fairly simple. At least two implementations already
provide some similar mechanism for suppressing messages.
Cost to users:
Some (non-portable) user code may break in implementations where this is
an incompatible change.
Specifying that the :PRINT argument defaults to NIL is consistent with
LOAD, but in most implementations the default now is to print out a
lot of information about each function or top-level form. Some users
may find it irritating to have to type in :print t to get the same
amount of information they're used to seeing.
Benefits:
Users are given a portable way to control how much information is printed
by COMPILE-FILE.
Proposal COMPILER-VERBOSITY:USE-CONDITIONS:
Add a new condition type, INFO. Require that there is a default
handler for conditions of type INFO which simple presents the message
to the user.
Rationale:
This allows informational compiler messages and compiler diagnostics
to be handled in a uniform manner with a simple, well defined way for
the user to gain any desired degree of control over these messages.
Current Practice:
Lucid provides a :MESSAGES keyword argument to COMPILE-FILE, which can
either be a stream to send progress messages to, or NIL to suppress messages.
The default value is T, which sends messages to "the standard terminal
device".
On the TI Explorer, COMPILE-FILE displays the name of the function being
compiled when the option :VERBOSE T is given or special variable
COMPILER:COMPILER-VERBOSE is true. (In other words, they use :VERBOSE
to mean what this proposal says to use :PRINT for.)
Cost to implementors:
This is an incompatible change for all implementations. It should be
a simple change to make once an implementation supports the condition
system.
All existing implementations can continue support their current
message control mechanisms as non portable interfaces to this new
technique.
Cost to users:
Some user code may break in implementations which remove any
(non-portable) existing mechanisms to control compiler output.
Benefits:
Users are given a portable way to control how much information is printed
by COMPILE-FILE.
Aesthetics:
Using a well defined, already existing, general mechanism is more
aesthetically pleasing than adding another ad-hoc flag or special
variable.
Discussion:
Rather than just treating :PRINT and :VERBOSE as boolean values, it
might be useful to have them convey more information. For example,
Pitman has suggested using keyword values like :BRIEF or :DETAILED to
allow varying amounts of information of each type to be printed.
Alternatively, it might be reasonable to follow Lucid's precedent to
allow the values of :PRINT and :VERBOSE to be streams to allow
messages to be directed somewhere other than *STANDARD-OUTPUT*.
Either of these suggestions could reasonably be made to apply to LOAD
as well, but the intent of this proposal is to make COMPILE-FILE
behave like LOAD, not to change the specification of LOAD.
Loosemore believes that using conditions for this purpose is not
appropriate, because this issue deals with messages indicating the
normal progress of the compiler and conditions are supposed to be used
to signal exceptional (non-ordinary) situations.
Pierson believes that conditions provide a well defined, portable,
non-intrusive interface for user control of infrequent events. While
the use of conditions is not notably efficient, compiler informational
messages are sufficiently infrequent that this should not impose a
noticeable performance penalty.
Pierson would like to see LOAD, etc. changed to also use this
interface.
∂12-Dec-88 1619 CL-Compiler-mailer Re: issue status, 12/12/88
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 12 Dec 88 16:18:57 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA19146; Mon, 12 Dec 88 16:21:20 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA02319; Mon, 12 Dec 88 16:17:59 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA11917; Mon, 12 Dec 88 16:18:49 PST
Date: Mon, 12 Dec 88 16:18:49 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8812130018.AA11917@clam.sun.com>
To: cl-compiler@sail.stanford.edu, sandra%defun@cs.utah.edu
Subject: Re: issue status, 12/12/88
> The following issues are those that I would like to finish up within the
> next week or so, with notes on what remains to be done.
> CONSTANT-COMPILABLE-TYPES
> We need a new draft of this proposal to incorporate the latest
> round of discussion. Cris???
I've been sick some lately (excuses, excuses), but have put in some work
on this, and will continue to do so. We need to get this proposal set
well enough for feedback from all X3J13'ers who want to, and get it set
before the next meeting. In my view there is too much content for a
vote in January, but with any luck at all we will have a good proposal.
-Cris
∂12-Dec-88 1700 CL-Compiler-mailer Re: issue status, 12/12/88 (issue COMPILER-DIAGNOSTICS)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Dec 88 17:00:00 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA00499; Mon, 12 Dec 88 17:59:06 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03353; Mon, 12 Dec 88 17:58:57 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812130058.AA03353@defun.utah.edu>
Date: Mon, 12 Dec 88 17:58:55 MST
Subject: Re: issue status, 12/12/88 (issue COMPILER-DIAGNOSTICS)
To: Dan L. Pierson <pierson@mist.encore.com>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Dan L. Pierson <pierson@mist.encore.com>, Mon, 12 Dec 88 17:52:29 EST
> Date: Mon, 12 Dec 88 17:52:29 EST
> From: Dan L. Pierson <pierson@mist.encore.com>
>
> COMPILER-DIAGNOSTICS
> The NOTICE condition type hasn't happened yet. I was going to change
> references to the NOTICE condition to the STYLE-WARNING condition,
> which is a subtype of warning (allowing user condition handlers to use
> the MUFFLE-WARNING restart on it to suppress the messages). Any
> objections?
>
> The NOTICE condition type is created by this proposal. There is no
> need for any other action. I object to its removal on the grounds
> that a separate issue to create it hasn't been passed in some other
> place (are you thinking of Cleanup?).
I believe that the original intent of the NOTICE condition type was to
make it something disjoint from SEVERE-CONDITION and WARNING, right?
As Pitman pointed out some time ago, introducing a new condition type
requires more than just saying it exists. Making the condition type
used for these kinds of compiler diagnostics a subtype of WARNING has
the advantage of simplicity -- it can simply borrow all the same
mechanisms as WARNING conditions, including the WARN function and the
MUFFLE-WARNING restart to disable printing of messages. Doing all of
this from scratch for a disjoint condition type would be more
complicated than I have the time to figure out right now. If you feel
ambitious enough to tackle this, feel free. I agree that there is no
inherent reason why we cannot define a new condition type on our own.
-Sandra
-------
∂12-Dec-88 1726 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Dec 88 17:26:42 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA01489; Mon, 12 Dec 88 18:25:53 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03383; Mon, 12 Dec 88 18:25:49 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812130125.AA03383@defun.utah.edu>
Date: Mon, 12 Dec 88 18:25:45 MST
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 3
To: Dan L. Pierson <pierson@mist.encore.com>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Dan L. Pierson <pierson@mist.encore.com>, Mon, 12 Dec 88 17:29:15 EST
> Date: Mon, 12 Dec 88 17:29:15 EST
> From: Dan L. Pierson <pierson@mist.encore.com>
>
> Once again it's
> supporting possibly broken current practice versus maintaining the
> traditional flexibility of Lisp.
This seems like a self contradiction -- obviously those
implementations whose current practice is "broken" don't have a
tradition of being flexible. (They have have a tradition of being
"broken", I guess.) :-)
All this talk about "tradition" depends on which "tradition" you're
most familiar with. Here at Utah we have the Portable Lisp Compiler
that goes back to around 1979ish, and it has always refused to handle
circular constants. Likewise the idea of coalescing isomorphic
constants has a long history in the MacLisp dialect. Historically,
most Lisp dialects have had some differences in semantics between
compiled and interpreted code. From my perspective, for example, it
seems to be traditional to leave constants alone in interpreted code,
but to allow both COMPILE and COMPILE-FILE to copy and coalesce and
barf on circularities.
-Sandra
-------
∂12-Dec-88 1749 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Dec 88 17:49:49 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA01906; Mon, 12 Dec 88 18:49:00 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03408; Mon, 12 Dec 88 18:48:57 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812130148.AA03408@defun.utah.edu>
Date: Mon, 12 Dec 88 18:48:56 MST
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Dan L. Pierson <pierson@mist.encore.com>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Dan L. Pierson <pierson@mist.encore.com>, Mon, 12 Dec 88 15:48:45 EST
> Date: Mon, 12 Dec 88 15:48:45 EST
> From: Dan L. Pierson <pierson@mist.encore.com>
>
> However, my position on this is not unalterable. I would like to see
> a writeup with more discussion that fairly presents both views. As
> with so many of the compiler issues, this one has gotten buried in
> such a torrent of mail that I can't keep track of all the arguments.
Sigh. It seemed like most of that "torrent of mail" was more heat
than light, but I thought I had managed to extract the main arguments
on both sides. It certainly wasn't my intention for the writeup to
squelch or misrepresent the viewpoint that I happen to personally
disagree with. If anybody wants to submit a *brief* argument (not
more than a couple paragraphs) to summarize their point of view, I'll
be happy to add it to the discussion section.
-Sandra
-------
∂13-Dec-88 1154 CL-Compiler-mailer Re: issue status, 12/12/88 (issue COMPILER-DIAGNOSTICS)
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 13 Dec 88 11:54:26 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA06943; Tue, 13 Dec 88 14:53:25 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA11815; Tue, 13 Dec 88 14:53:34 EST
Message-Id: <8812131953.AA11815@mist.>
To: "sandra%defun@cs.utah.edu"@multimax.encore.com (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue status, 12/12/88 (issue COMPILER-DIAGNOSTICS)
In-Reply-To: Your message of Mon, 12 Dec 88 17:58:55 -0700.
<8812130058.AA03353@defun.utah.edu>
Date: Tue, 13 Dec 88 14:53:31 EST
From: Dan L. Pierson <pierson@mist.encore.com>
I believe that the original intent of the NOTICE condition type was to
make it something disjoint from SEVERE-CONDITION and WARNING, right?
As Pitman pointed out some time ago, introducing a new condition type
requires more than just saying it exists. Making the condition type
used for these kinds of compiler diagnostics a subtype of WARNING has
the advantage of simplicity -- it can simply borrow all the same
mechanisms as WARNING conditions, including the WARN function and the
MUFFLE-WARNING restart to disable printing of messages. Doing all of
this from scratch for a disjoint condition type would be more
complicated than I have the time to figure out right now. If you feel
ambitious enough to tackle this, feel free. I agree that there is no
inherent reason why we cannot define a new condition type on our own.
Actually, there isn't that much special about warnings in the
condition system (Rev 18, as passed at the June meeting):
WARN string &rest arguments
Can't be used because it signals exactly type WARN, not a subtype.
WARN condition &rest arguments
Useable, but no advantage; it's the same (except for trivial
error checking) as:
SIGNAL condition &rest argments
*BREAK-ON-WARNINGS*
Obsolete, use *BREAK-ON-SIGNALS*.
MUFFLE-WARNING
Would be useful, but since it's just a standard function it
would be easy to add another one. However, This is one of the
two strongest arguments in favor of making NOTICE and INFO
subtypes of WARNING.
The real issue is the CONDITION type hierarchy. It currently looks like:
CONDITION
|
+--------------+------+----------------+---- . . .
| | |
| | |
SIMPLE-CONDITION SERIOUS-CONDITION WARNING
| |
| |
| SIMPLE-WARNING
|
|
+-----+--------------------------+--- . . .
| |
| |
ERROR STORAGE-CONDITION
|
|
+------------+--+-------------------+--- . . .
| | |
| | |
SIMPLE-ERROR ARITHMETIC-ERROR CONTROL-ERROR
| |
. . . . . .
It is explicitly legal to add new intermediate types as long as the
specified subtype and disjointess relationships are not violated. As
I see it, we have the following options:
1. Make NOTICE (and INFO subtypes of WARNING). This supports
unchanged to use MUFFLE-WARNING, and *BREAK-ON-WARNINGS* but
does not allow the use of WARN. My objection to this is that I
want the INFO condition and I just can't see INFO as a type of
WARNING. The biggest advantage of this is that it doesn't
change the second level of the current condition hierarchy.
2. Add a new subtype of CONDITION, say MESSAGE, with WARN, NOTICE,
and INFO as subtypes. Add the restart function MUFFLE-MESSAGE.
This supports MUFFLE-MESSAGE, *BREAK-ON-SIGNALS*, and SIGNAL.
Some people might well object that WARNING should be disjoint
from both MESSAGE and ERROR.
3. Add a new subtype of CONDITION, say MESSAGE, with NOTICE, and
INFO as subtypes. Add the restart function MUFFLE-MESSAGE.
This supports (and requires) MUFFLE-MESSAGE, MUFFLE-WARNING,
*BREAK-ON-SIGNALS*, and SIGNAL.
All in all, I slightly prefer 3, could easily be convinced by 2 and am
just not fond of 1. I don't see this as a tremendous problem, so if
people (especially Kent) agree, I'll be glad to write this up, either
as part of COMPILER-DIAGNOSTICS or COMPILER-VERBOSITY, or as (sigh)
yet another proposal.
∂13-Dec-88 1340 CL-Compiler-mailer Re: issue status, 12/12/88 (issue COMPILER-DIAGNOSTICS)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Dec 88 13:40:13 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA01815; Tue, 13 Dec 88 14:39:25 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA04030; Tue, 13 Dec 88 14:39:22 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812132139.AA04030@defun.utah.edu>
Date: Tue, 13 Dec 88 14:39:21 MST
Subject: Re: issue status, 12/12/88 (issue COMPILER-DIAGNOSTICS)
To: Dan L. Pierson <pierson@mist.encore.com>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Dan L. Pierson <pierson@mist.encore.com>, Tue, 13 Dec 88 14:53:31 EST
Yes, I also agree that #3 is the best alternative. If you have the
time to work on such a thing, that's great.
-Sandra
-------
∂13-Dec-88 2003 CL-Compiler-mailer issue CONSTANT-COLLAPSING, version 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Dec 88 20:03:47 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 508201; Tue 13-Dec-88 23:00:48 EST
Date: Tue, 13 Dec 88 23:00 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CONSTANT-COLLAPSING, version 2
To: sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8812122011.AA03239@defun.utah.edu>
Message-ID: <881213230031.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
It's a bad idea for one proposal to rely so heavily on another.
A phrase like "if they are equivalent under the relationship
specified in issue CONSTANT-COMPILABLE-TYPES" is too vague for
this proposal to be submitted in isolation. You might as well
bundle the two together as one proposal since they're so
intertwined anyway.
In particular, subtleties like whether the predicate described
in the other proposal is universally applicable affect this
proposal in dramatic ways. If, for example, that predicate is
not well-defined on some kinds of data (eg, circular structures),
then it's not clear whether this proposal implies that the compiler
will blow out in those ill-defined cases (since there's no mention
of whether the function is actually applied, or if it's just a
way for the user to know if collapsing might occur).
Further, you don't specify whether this is true of EVAL and COMPILE
or only of COMPILE-FILE. The stuff in CONSTANT-COLLAPSABLE-TYPES
may end up (if I get my way) being only about file compilation.
This proposal, however, does not claim to be only about file
compilation, so if we're not careful, we could end up having
CONSTANT-COLLAPSABLE-TYPES end up applying to non-file compilation
by some strange implications arising from strange and unforseen
coupling effects of these proposals.
[It's getting to the point where in discussing any of these proposals
you have to be extremely clear about not only which proposals (and
versions) you're considering, but also which proposals (and versions)
you're not considering as part of the Universe. This is not a good
thing.]
∂14-Dec-88 0035 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 14 Dec 88 00:34:59 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA07227g; Wed, 14 Dec 88 00:32:11 PST
Received: by bhopal id AA12088g; Wed, 14 Dec 88 00:34:11 PST
Date: Wed, 14 Dec 88 00:34:11 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812140834.AA12088@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 10 Dec 88 12:12:08 MST <8812101912.AA02084@defun.utah.edu>
Subject: issue QUOTE-MAY-COPY, version 2
A few little points:
re: QUOTE-MAY-COPY:ALWAYS
To me, the choice of names for this alternative is somewhat loaded; it
seems to imply "excesssive, copying work must ALWAYS take place". How
about a name like EXPLICITLY-VAGUE? At issue is not the requirement
to do copying at all, but merely the prohibition from depending on the
address of the constant obtained from the special form (QUOTE <foo>).
re: If an implementation chooses to copy constants, the copying may only
happen once each time the form containing the constant is processed
with COMPILE or EVAL (see examples below).
This seems a bit fuzzy to me. Why not simply say that successive
evaluations of a form (QUOTE <foo>) must all be EQL? then you could
point out in an implementational note that this means you are restricted
to copying a given instance of a constant at most once.
I'd like to see a bit more of the burden laid on the feet of those who
feel that it is so important to retain EQ-semantics for quoted constants.
That is _definitely_ not the current practice for compiled files; so
how can reasonable, portable programs depend on this mistaken notion?
True, no current EVAL implementation goes to the effort to do anything
other than return a piece of the encoded program; but slightly more
clever interpreters/compilers could do so. An EXPLICITLY-VAGUE proposal
simply gives an implementor the license to do the same tricks for EVAL
that so many do for COMPILE-FILE.
-- JonL --
∂14-Dec-88 0146 CL-Compiler-mailer I still need help with compile-time side-effects
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 14 Dec 88 01:46:13 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA07363g; Wed, 14 Dec 88 01:43:21 PST
Received: by bhopal id AA12154g; Wed, 14 Dec 88 01:45:19 PST
Date: Wed, 14 Dec 88 01:45:19 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812140945.AA12154@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cl-object-oriented-programming@sail.stanford.edu,
cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 10 Dec 88 13:48:42 MST <8812102048.AA02145@defun.utah.edu>
Subject: I still need help with compile-time side-effects
re: I haven't yet gotten any response to my earlier plea for help about
what the compile-time side-effects of the CLOS defining macros should be.
Although I volunteered (at Fairfax) to help out with specifying these
requirements, I find myself so overloaded with "Cleanup" questions and
other X3J13 responsibilities that I have no time to work on this issue
before Spring 1989. I'm sorry I can't be of more help now.
-- JonL --
∂14-Dec-88 0814 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 14 Dec 88 08:14:35 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA27472; Wed, 14 Dec 88 09:13:41 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA04469; Wed, 14 Dec 88 09:13:38 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812141613.AA04469@defun.utah.edu>
Date: Wed, 14 Dec 88 09:13:36 MST
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Jon L White <jonl@lucid.com>
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: Jon L White <jonl@lucid.com>, Wed, 14 Dec 88 00:34:11 PST
> Date: Wed, 14 Dec 88 00:34:11 PST
> From: Jon L White <jonl@lucid.com>
>
> re: QUOTE-MAY-COPY:ALWAYS
>
> To me, the choice of names for this alternative is somewhat loaded; it
> seems to imply "excesssive, copying work must ALWAYS take place". How
> about a name like EXPLICITLY-VAGUE?
Fine with me.
> re: If an implementation chooses to copy constants, the copying may only
> happen once each time the form containing the constant is processed
> with COMPILE or EVAL (see examples below).
>
> This seems a bit fuzzy to me. Why not simply say that successive
> evaluations of a form (QUOTE <foo>) must all be EQL? then you could
> point out in an implementational note that this means you are restricted
> to copying a given instance of a constant at most once.
Frankly, your wording seems too vague to me. I think it's important
to address the issues of what happens when the QUOTE form appears
inside of something passed to EVAL. If EVAL is doing the copying in
some kind of preprocessor, then it is reasonable for each call to EVAL
to make its own copy. Likewise, I think we must allow for the
possibility that COMPILE might make a fresh copy of all constants
inside the function whenever it is recompiled. Perhaps I can think of
some better wording to express this, though.
-Sandra
-------
∂14-Dec-88 0902 CL-Compiler-mailer Re: issue CONSTANT-COLLAPSING, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 14 Dec 88 09:01:55 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA29609; Wed, 14 Dec 88 10:00:48 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA04492; Wed, 14 Dec 88 10:00:30 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812141700.AA04492@defun.utah.edu>
Date: Wed, 14 Dec 88 10:00:29 MST
Subject: Re: issue CONSTANT-COLLAPSING, version 2
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 13 Dec 88 23:00 EST
While this specific -proposal- is closely linked to issue
CONSTANT-COMPILABLE-TYPES, the -issue- itself is not. The first
version defined its own "collapsing predicate", and Bob Kerns at one
point suggested that the "collapsing predicate" should be EQL.
All of the issues involving constants are controversial and most of
them are largely independent of each other. I think it would be a
mistake to lump all of the questions together under one mega-proposal,
particularly since we here in the committee have been unable to reach
consensus on some of them.
My current intent is that issues CONSTANT-COLLAPSING,
CONSTANT-COMPILABLE-TYPES, and CONSTANT-CIRCULAR-COMPILATION would
initially apply only to COMPILE-FILE, and that the outcome of issue
QUOTE-MAY-COPY will be used to determine whether the same constraints
that apply to COMPILE-FILE must also apply to COMPILE and possibly
EVAL. I will try to make sure that the next versions of the writeups
on all of these issues make that more clear.
-Sandra
-------
∂14-Dec-88 0951 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 14 Dec 88 09:51:47 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA28430; Wed, 14 Dec 88 09:53:41 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA26739; Wed, 14 Dec 88 09:48:45 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA14336; Wed, 14 Dec 88 09:49:40 PST
Date: Wed, 14 Dec 88 09:49:40 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8812141749.AA14336@clam.sun.com>
To: jonl@lucid.com, sandra%defun@cs.utah.edu
Subject: Re: issue QUOTE-MAY-COPY, version 2
Cc: cl-compiler@sail.stanford.edu
> I'd like to see a bit more of the burden laid on the feet of those who
> feel that it is so important to retain EQ-semantics for quoted constants.
> That is _definitely_ not the current practice for compiled files; so
> how can reasonable, portable programs depend on this mistaken notion?
Let's do a thought experiment where there is a file "compiler" of the
kind described at one time by Sandra: Roughly speaking, it READs forms
from a file, macroexpands them, EVALs some at "compile" time, and
PRINTs (or perhaps something else rather like it) the macroexpanded
forms to an output file.
Now suppose that QUOTE "never copies". Load a source file, compile
it with this super-trivial compiler, get a pointer to at least one
of the quoted constants, then load the "compiled" output
of the compiler. Now compare the original quoted constant
that appeared in the source against the corresponding quoted constant
in the "compiled" code. They are not EQ. In fact they appear to be
copies, yet QUOTE *never copies*.
I claim that the apparent copying "isn't QUOTE's fault", and that
it happens regardless of the semantics of quote.
∂14-Dec-88 1300 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 1
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 14 Dec 88 13:00:12 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA05778; Wed, 14 Dec 88 13:02:27 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA06174; Wed, 14 Dec 88 12:59:00 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA14699; Wed, 14 Dec 88 12:59:57 PST
Date: Wed, 14 Dec 88 12:59:57 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8812142059.AA14699@clam.sun.com>
To: jonl@lucid.com
Subject: Re: issue QUOTE-MAY-COPY, version 1
Cc: cl-compiler@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Taking this opportunity to also respond to a related earlier note
of JonL's:
> . . .
>
> However, I don't think it is right to say that READ constructs up
> "constants". Note that READ absolutely cannot know whether some structure
> it cons'd up is a constant or not. A piece of data only becomes a program
> "constant" when it is EVAL'd in the proper context (or "compiled");
> otherwise, it is just as random as any other cons cell or string lying
> around in memory. . . .
My personal intuition is that (potentially) readonly constants are
created sometime during loading of a compiled file, and that as far
as a user of the language is concerned, the constants are *created*
in their coalesced, copied, readonly, or whatever state.
There may be other self-consistent and reasonable points of view. This
point of view makes sense to me, fits CLtL's existing specification of
QUOTE, and I think satisfies Pitman's concerns.
∂15-Dec-88 0832 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 15 Dec 88 08:30:50 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa05275; 15 Dec 88 15:44 GMT
Date: Thu, 15 Dec 88 15:55:52 GMT
Message-Id: <6278.8812151555@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: sandra <@cs.utah.edu:sandra@defun>,
Jon L White <@sail.stanford.edu:jonl@lucid.com>
In-Reply-To: Sandra J Loosemore's message of Wed, 14 Dec 88 09:13:36 MST
Cc: cl-compiler@sail.stanford.edu
> > Date: Wed, 14 Dec 88 00:34:11 PST
> > From: Jon L White <jonl@lucid.com>
> >
> > re: QUOTE-MAY-COPY:ALWAYS
> >
> > To me, the choice of names for this alternative is somewhat loaded; it
> > seems to imply "excesssive, copying work must ALWAYS take place". How
> > about a name like EXPLICITLY-VAGUE?
>
> Fine with me.
It does say "MAY-COPY", so I don't understand it as "must copy".
Anyway, I don't really like EXPLICITLY-VAGUE. Is there some better
way to say "allowed by not requried"? I'd suggest UNSPECIFIED, but
that too may sound loaded. Don't we need some general way to say this
sort of thing in the standard?
-- Jeff
∂15-Dec-88 0843 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 15 Dec 88 08:43:27 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06125; Thu, 15 Dec 88 09:42:31 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05121; Thu, 15 Dec 88 09:42:24 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812151642.AA05121@defun.utah.edu>
Date: Thu, 15 Dec 88 09:42:21 MST
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: sandra <sandra%defun@cs.utah.edu>,
Jon L White <@sail.stanford.edu:jonl@lucid.com>,
cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Thu, 15 Dec 88 15:55:52 GMT
Well, I'm willing to call the proposal whatever makes everybody else
happy. If we want a long name, how about ALWAYS-ALLOWED-BUT-NEVER-REQUIRED,
or for a short one, how about just plain YES?
-Sandra
-------
∂15-Dec-88 1208 CL-Compiler-mailer Issue: COMPILER-VERBOSITY (Version 3)
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 15 Dec 88 12:07:45 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA02462; Thu, 15 Dec 88 15:06:38 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA01233; Thu, 15 Dec 88 15:06:31 EST
Message-Id: <8812152006.AA01233@mist.>
To: cl-compiler@sail.stanford.edu
Subject: Issue: COMPILER-VERBOSITY (Version 3)
Date: Thu, 15 Dec 88 15:06:30 EST
From: Dan L. Pierson <pierson@mist.encore.com>
Forum: Compiler
Issue: COMPILER-VERBOSITY
References: CLtL p. 438-329; 426
issue COMPILER-DIAGNOSTICS
Category: CHANGE/CLARIFICATION/ENHANCEMENT
Edit History: V1, 25 Oct 1988, Sandra Loosemore
V2, 12 Dec 1988, Dan L. Pierson (add USE-CONDITIONS)
V3, 15 Dec 1988, Dan L. Pierson (expand on conditions)
Problem Description:
Implementations vary widely in the amount of information that is printed
out by COMPILE-FILE. In some situations, it would be useful to control
how much information is printed.
Proposal COMPILER-VERBOSITY:LIKE-LOAD:
Introduce a special variable, *COMPILE-VERBOSE*, with an implementation-
dependent initial value.
Add :VERBOSE and :PRINT keyword arguments to the function COMPILE-FILE,
analogous to those for the function LOAD.
The :VERBOSE argument (which defaults to the value of *COMPILE-VERBOSE*),
if true, permits COMPILE-FILE to print a message in the form of a comment
to *STANDARD-OUTPUT* indicating what file is being compiled and other
useful information.
The :PRINT argument (which defaults to NIL), if true, causes
information about top-level forms in the file being compiled to be
printed to *STANDARD-OUTPUT*. Exactly what is printed will vary from
implementation to implementation, but nevertheless some information
will be printed.
Rationale:
This proposal makes COMPILE-FILE behave like LOAD. There is already
some precedent for doing this (for example, issue COMPILE-FILE-PACKAGE,
which makes COMPILE-FILE as well as LOAD rebind *PACKAGE*).
Current Practice:
Lucid provides a :MESSAGES keyword argument to COMPILE-FILE, which can
either be a stream to send progress messages to, or NIL to suppress messages.
The default value is T, which sends messages to "the standard terminal
device".
On the TI Explorer, COMPILE-FILE displays the name of the function being
compiled when the option :VERBOSE T is given or special variable
COMPILER:COMPILER-VERBOSE is true. (In other words, they use :VERBOSE
to mean what this proposal says to use :PRINT for.)
Cost to implementors:
This is an incompatible change for some implementations, but the changes
required should be fairly simple. At least two implementations already
provide some similar mechanism for suppressing messages.
Cost to users:
Some (non-portable) user code may break in implementations where this is
an incompatible change.
Specifying that the :PRINT argument defaults to NIL is consistent with
LOAD, but in most implementations the default now is to print out a
lot of information about each function or top-level form. Some users
may find it irritating to have to type in :print t to get the same
amount of information they're used to seeing.
Benefits:
Users are given a portable way to control how much information is printed
by COMPILE-FILE.
Proposal COMPILER-VERBOSITY:USE-CONDITIONS:
Add the new subtype of CONDITION, MESSAGE, defined in
COMPILER-DIAGNOSTICS (V5). Add a new subtype of MESSAGE, INFO.
Require compilers to "print" all messages covered by this proposal by
signalling conditions of type INFO.
Rationale:
This allows informational compiler messages and compiler diagnostics
to be handled in a uniform manner with a simple, well defined way for
the user to gain any desired degree of control over these messages.
Current Practice:
No one currently controls compiler messages via the condition system.
Cost to implementors:
This is an incompatible change for all implementations. It should be
a simple change to make once an implementation supports the condition
system.
All existing implementations can continue support their current
message control mechanisms as non portable interfaces to this new
technique.
Cost to users:
Some user code may break in implementations which remove any
(non-portable) existing mechanisms to control compiler output.
Benefits:
Users are given a portable way to control how much information is printed
by COMPILE-FILE.
Aesthetics:
Using a well defined, already existing, general mechanism is more
aesthetically pleasing than adding another ad-hoc flag or special
variable.
Discussion:
Rather than just treating :PRINT and :VERBOSE as boolean values, it
might be useful to have them convey more information. For example,
Pitman has suggested using keyword values like :BRIEF or :DETAILED to
allow varying amounts of information of each type to be printed.
Alternatively, it might be reasonable to follow Lucid's precedent to
allow the values of :PRINT and :VERBOSE to be streams to allow
messages to be directed somewhere other than *STANDARD-OUTPUT*.
Either of these suggestions could reasonably be made to apply to LOAD
as well, but the intent of this proposal is to make COMPILE-FILE
behave like LOAD, not to change the specification of LOAD.
Loosemore believes that using conditions for this purpose is not
appropriate, because this issue deals with messages indicating the
normal progress of the compiler and conditions are supposed to be used
to signal exceptional (non-ordinary) situations.
Pierson believes that conditions provide a well defined, portable,
non-intrusive interface for user control of infrequent events. While
the use of conditions is not notably efficient, compiler informational
messages are sufficiently infrequent that this should not impose a
noticeable performance penalty.
Pierson would like to see LOAD, etc. changed to also use this
interface.
∂15-Dec-88 1207 CL-Compiler-mailer Issue: COMPILER-DIAGNOSTICS (Version 5)
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 15 Dec 88 12:06:41 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA02454; Thu, 15 Dec 88 15:05:32 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA01226; Thu, 15 Dec 88 15:05:25 EST
Message-Id: <8812152005.AA01226@mist.>
To: cl-compiler@sail.stanford.edu
Subject: Issue: COMPILER-DIAGNOSTICS (Version 5)
Date: Thu, 15 Dec 88 15:05:23 EST
From: Dan L. Pierson <pierson@mist.encore.com>
Note that I've copied the "Forum" header item from Guy.
Forum: Compiler
Issue: COMPILER-DIAGNOSTICS
References: CLtL p. 438-439
Condition System, Revision #18
S:>KMP>cl-conditions.text.34
Issue GC-MESSAGES
Issue RETURN-VALUES-UNSPECIFIED
Issue COMPILER-VERBOSITY
Category: CLARIFICATION, ENHANCEMENT
Edit History: V1, 15 Oct 1988, Sandra Loosemore
V2, 19 Oct 1988, Sandra Loosemore (minor fixes)
V3, 25 Oct 1988, Sandra Loosemore (input from Pitman & Gray)
V4, 01 Nov 1988, Sandra Loosemore (fix typos)
V5, 15 Dec 1988, Sandra Loosemore
Dan L. Pierson (new condition types)
Problem Description:
It is unclear whether various diagnostics issued by the compiler are
supposed to be true errors and warnings, or merely messages.
In some implementations, COMPILE-FILE handles even serious error
situations (such as syntax errors) by printing a message and then
trying to recover and continue compiling the rest of the file, rather
than by signalling an error. While this user interface style is just
as acceptable as invoking the debugger, it means that a normal return
from COMPILE-FILE does not necessarily imply that the file was
successfully compiled.
Many compilers issue warnings about programming style issues (such as
binding a variable that is never used but not declared IGNORE).
Sometimes these messages obscure warnings about more serious problems,
and there should be some way to differentiate between the two. For
example, it should be possible to suppress the style warnings.
Also, neither CLtL nor issue RETURN-VALUES-UNSPECIFIED states what the
return value from COMPILE-FILE should be.
Proposal COMPILER-DIAGNOSTICS:USE-HANDLER:
(1) Clarify that COMPILE-FILE is allowed to print messages to
*STANDARD-OUTPUT* indicating the normal progress of the compilation.
(See issue COMPILER-VERBOSITY.)
(2) Clarify that both ERROR and WARNING conditions may be signalled within
COMPILE or COMPILE-FILE, including arbitrary errors which may occur
due to compile-time processing of (EVAL-WHEN (COMPILE) ...) forms or
macro expansion.
Considering only those conditions signalled -by- the compiler (as
opposed to -within- the compiler),
(a) Conditions of type ERROR may be signalled by the compiler in
situations where the compilation cannot proceed without
intervention.
Examples:
syntax errors
(b) Conditions of type WARNING may be signalled by the compiler in
situations where the standard explicitly states that a warning must,
should, or may be signalled; and where the compiler can determine
that a situation that "is an error" would result at runtime.
Examples:
violation of type declarations
SETQ'ing a constant defined with DEFCONSTANT
calls to built-in Lisp functions with wrong number of arguments
referencing a variable declared IGNORE
(c) Add a new subtype of CONDITION named MESSAGE, with a subtype NOTICE.
Specify that the default handler for conditions of type MESSAGE
simply prints the message datum and continues. Add a new standard
restart function MUFFLE-MESSAGE analogous to MUFFLE-WARNING.
(d) All other diagnostics issued by the compiler should be conditions
of type NOTICE. In particular, this category includes all
diagnostics about matters of programming style. Although
conditions of type NOTICE -may- be signalled in these situations,
no implementation is -required- to do so. However, if an
implementation does choose to signal a condition, that condition
will be of type NOTICE.
Examples:
redefinition of function with different argument list
unreferenced local variables not declared IGNORE
(3) Require COMPILE-FILE to establish an error handler. Add a :HANDLER
keyword argument to COMPILE-FILE, which is a user condition
handler function which is to be used during compilation. If the
user error handler is not supplied or declines to handle a condition,
then the compiler's error handler will be invoked. Require the
compiler's error handler to handle the ABORT restart by aborting
the smallest feasible part of the compilation.
(4) Specify that COMPILE-FILE returns three values. The first value is the
truename of the output file, or NIL if the file could not be created.
The second value is non-NIL if errors were signalled during compilation
(indicating that the output file is almost certainly unusable). The
third value is non-NIL if warnings were signalled during compilation
(indicating that the output file may or may not be usable).
(5) Clarify that COMPILE does not establish a condition handler. Instead,
it uses whatever condition handler has been established in the environment
from which it is called.
Rationale:
Point by point,
(1) This reflects current practice.
(2) Conditions such as syntax errors which are errors in the interpreter
remain errors in the compiler. The division of other conditions
into WARNINGs and NOTICEs allows potentially serious problems to be
distinguished from mere kibbitzing on the part of the compiler.
(2c) The new condition types MESSAGE and NOTICE are structured to allow
this part of the condition hierarchy to be further extended. In
particular, the issue COMPILER-VERBOSIY proposes an additional
subtype of MESSAGE named INFO. Note that an analogue to
*BREAK-ON-WARNINGS* is not needed because MESSAGE conditions
"never" cause a break (i.e. not unless a user-defined handler
causes one).
(3) It is reasonable for the default handling of compiler errors not to
cause the debugger to be invoked. However, any error handler
established by COMPILE-FILE would override handlers established by the
user in the surrounding environment.
Requiring the compiler's error handler to handle the ABORT restart
reflects what several implementations already do (although probably not
using this mechanism). The intent of the wording is to allow an
implementation to abort the entire file compilation if it is not
feasible to abort a smaller part.
(4) This allows users to determine whether or not COMPILE-FILE is able to
actually compile the file successfully. Returning several values is
is more useful than a single success/failure value because there are
several degrees of failure.
(5) This is to reflect the use of COMPILE-FILE as being more "batch"-oriented
and COMPILE as being more interactive. There is less motivation to have
COMPILE try to recover from errors without user interaction.
Current Practice:
No implementation behaves exactly as specified in this proposal.
In VaxLisp, COMPILE-FILE handles most compile-time errors without
invoking the debugger. (It gives up on that top-level form and moves on
to the next one.) Instead of signalling errors or warnings, it simply
prints them out as messages.
In Lucid Common Lisp, COMPILE-FILE invokes the debugger when it encounters
serious problems. COMPILE-FILE returns the pathname for the output file.
Symbolics Genera usually tries to keep compiling when it encounters errors;
so does Symbolics Cloe.
On the TI Explorer, the compiler tries to catch most errors and turn
them into warnings (except for errors on opening a file), but the user
can change special variable COMPILER:WARN-ON-ERRORS to NIL if he wants
to enter the debugger on an error signalled during reading, macro
expansion, or compile-time evaluation. The true name of the output
file is returned as the first value. A second value indicates whether
any errors or warnings were reported.
Cost to implementors:
The cost to implementors is not trivial but not particularly high. This
proposal tries to allow implementations considerable freedom in what
kinds of conditions the compiler must detect and how they are handled,
while still allowing users some reasonably portable ways to deal with
compile-time errors.
Cost to users:
This is a compatible extension. This proposal may cause users to see
some small differences in the user interface to the compiler, but
implementations already vary quite widely in their approaches. Some
users will probably have to make some minor changes to their code.
Benefits:
Users are given a way to detect and handle compilation errors, which
would simplify the implementation of portable code-maintenance
utilities. The behavior of the compiler in error situations is made
more uniform across implementations.
Discussion:
The issue of normal progress messages from the compiler is discussed
in more detail in a separate issue, COMPILER-VERBOSITY.
Pitman says that he would like to require COMPILE-FILE's error handler
never to invoke the debugger. I have left that out of this proposal
because it seems like an unnecessary restriction; if users want to ensure
that kind of behavior it is possible to do so by supplying a user error
handler. (Of course, the converse is also true.)
Sections 2b and 2d need more work. In CLtL, everything has been lumped
together as warnings, but there seems to be general agreement that
some things (like complaints about unused variables) should really be
notices instead. Basically we need to go through and find every place
where CLtL says that the compiler might issue a warning and decide what
category it belongs in, and list it here.
If the condition system is integrated with CLOS or otherwise comes to
support multiple inheritance, we might consider introducing a
COMPILER-CONDITION that can be used in mixins with the other condition
types, so that error handlers can distinguish between errors signalled
by the compiler itself and errors signalled during macroexpansion or
EVAL-WHEN processing.
Gray would like to exclude errors resulting from failure to open the
input and output files from the compiler's error handling. The
proposal should probably be specific about this, one way or the other.
∂15-Dec-88 1213 CL-Compiler-mailer Re: Issue: COMPILER-DIAGNOSTICS (Version 5)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 15 Dec 88 12:13:53 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA13444; Thu, 15 Dec 88 13:13:02 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05246; Thu, 15 Dec 88 13:12:58 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812152012.AA05246@defun.utah.edu>
Date: Thu, 15 Dec 88 13:12:56 MST
Subject: Re: Issue: COMPILER-DIAGNOSTICS (Version 5)
To: Dan L. Pierson <pierson@mist.encore.com>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Dan L. Pierson <pierson@mist.encore.com>, Thu, 15 Dec 88 15:05:23 EST
Sigh. You seem to have lost the changes I put in before sending this
to you. I'll see if I can come up with a version that incorporates both
your changes and mine.
-Sandra
-------
∂15-Dec-88 1853 CL-Compiler-mailer dumping weird objects to compiled files
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 15 Dec 88 18:53:10 PST
Posted-Date: Thu, 15 Dec 88 18:52:28 PST
Message-Id: <8812160252.AA06530@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.59/5.51)
id AA06530; Thu, 15 Dec 88 18:52:31 PST
To: common-lisp@sail.stanford.edu, cl-compiler@sail.stanford.edu
Cc: lwolf%franz.uucp@berkeley.edu
Subject: dumping weird objects to compiled files
Date: Thu, 15 Dec 88 18:52:28 PST
From: Don Cohen <donc@vaxa.isi.edu>
The commonlisp spec is quite vague on what exactly the compiler
should do and provides no control over how or whether strange
objects can be dumped at all. However, in the case of structures
it does provide for a print function. Suppose I have a function
F that uses a macro M which expands into some structure of type S.
1. If I give S a print function, can I expect that when I compile F
to a file, that print function will be used to write something to
the compiled file that will be read to return the "corresponding"
object when the file is loaded? (I'm interested in justifications
for either answer.) The other possibility is that the compiler
would ignore the print function and dump something that would,
when loaded, create a structure of type S and fill its slots with
objects that were recursively dumped. If I could count on my print
function being used, I could arrange for it to print something that
would "do the right thing".
2. If you don't think that my expectation is justified, do you
think the commonlisp spec ought to say that it is (thereby making
it so).
This "trick" would allow us to write a macro that allows macros
to generate the analog of #, which I think is a feature sorely
missed in commonlisp. This in turn would go a long way toward
solving what I regard as a problem with the spec - that EQUAL
values may be identified. This is a solution just because it
returns control over what things are EQ to the user, who knows
which things he wants to be EQ, which things he does NOT want EQ
and which don't matter.
∂16-Dec-88 0141 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 16 Dec 88 01:41:32 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00987g; Fri, 16 Dec 88 01:38:26 PST
Received: by bhopal id AA21021g; Fri, 16 Dec 88 01:40:26 PST
Date: Fri, 16 Dec 88 01:40:26 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812160940.AA21021@bhopal>
To: cperdue@Sun.COM
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: Cris Perdue's message of Wed, 14 Dec 88 09:49:40 PST <8812141749.AA14336@clam.sun.com>
Subject: issue QUOTE-MAY-COPY, version 2
re: I claim that the apparent copying "isn't QUOTE's fault", and that
it happens regardless of the semantics of quote.
Interesting "gedanken" experiment. In upshot, however, it seems that
you are _supporting_ the semantics of "QUOTE may copy", right? Because,
as you say, there are situations wherein one can't avoid it regardless
of how one implements quote
-- JonL --
∂16-Dec-88 0733 CL-Compiler-mailer Re: dumping weird objects to compiled files
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Dec 88 07:32:56 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06704; Fri, 16 Dec 88 08:31:57 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05675; Fri, 16 Dec 88 08:31:53 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812161531.AA05675@defun.utah.edu>
Date: Fri, 16 Dec 88 08:31:51 MST
Subject: Re: dumping weird objects to compiled files
To: Don Cohen <donc@vaxa.isi.edu>
Cc: common-lisp@sail.stanford.edu, cl-compiler@sail.stanford.edu,
lwolf%franz.uucp@berkeley.edu
In-Reply-To: Don Cohen <donc@vaxa.isi.edu>, Thu, 15 Dec 88 18:52:28 PST
The cl-compiler subcommittee is in the midst of preparing a set of
elaborate proposals to submit to X3J13 to detail exactly what kinds of
constant objects may be compiled. We do think it is important for the
ANSI standard to say more than CLtL does about this.
At the moment we appear to be heading towards the conclusion that the
dump/load transformation on structures created with DEFSTRUCT ought to
always create a structure isomorphic to the original, regardless of
whether or not that structure type has a user-supplied :PRINT-FUNCTION.
However, we have also talked about something similar to the dump/load
protocol you describe in the context of arbitrary CLOS objects.
-Sandra
-------
∂16-Dec-88 0843 Common-Lisp-mailer Re: dumping weird objects to compiled files
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 16 Dec 88 08:43:29 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA27569; Fri, 16 Dec 88 08:45:46 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA02972; Fri, 16 Dec 88 08:42:27 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA17011; Fri, 16 Dec 88 08:43:24 PST
Date: Fri, 16 Dec 88 08:43:24 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8812161643.AA17011@clam.sun.com>
To: cl-compiler@sail.stanford.edu, donc@vaxa.isi.edu
Subject: Re: dumping weird objects to compiled files
Cc: common-lisp@sail.stanford.edu, lwolf%franz.uucp@berkeley.edu
Hi Don!
I'm working on a proposal on this exact issue, i.e. what Common
Lisp is supposed to do about (quoted) constants in compiled files.
There are big holes in the definition of Common Lisp today
concerning compilation, and this is one of them.
To answer one of your questions, no you definitely cannot
expect your constants to be PRINTed into compiled files. Most
implementations use some binary representation of data.
There is interest in supporting user-defined types (structures
and classes) with user-definable dumpers, but it's just too much
work for me to personally try to address that. Hopefully some
good facility will get defined.
There is also interest in something comparable to #, that is not
a readmacro, so you can sensibly generate them in programs and
at least one proposal for that.
You can mail to me for more information.
-Cris
∂16-Dec-88 1254 CL-Compiler-mailer quoted constants
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 16 Dec 88 12:50:35 PST
Date: 16 Dec 88 12:42:15 EST
From: Timothy Daly <DALY@ibm.com>
To: cl-compiler@sail.stanford.edu
Message-Id: <121688.124216.daly@ibm.com>
Subject: quoted constants
Cris,
Since we've tripped over the subject of quoted constants and the
compiler I have a question. Is it valid for the compiler/interpreter
to assume that a quoted constant is read-only? That is, is this
code valid in all implementations:
(let ((x '(nil))) (rplaca x 3))
It turns out that Lucid will assume that quoted constants ARE
read-only. The implications of this are that quoted constants can
be placed in read-only storage and the garbage collector can assume
that these need not be traversed. There is a hole (feature? bug?)
in lucid common lisp that allows this code to work provided that
you have executed it interpretively since the quoted constants will
not be stuck into read-only storage for efficiency reasons. However,
if two garbage collections occur then you will probably have
lost the pointer (with 'undefined results').
It seems to me that the above code should be defined as valid
common lisp. Please try to clarify this issue.
tim
DALY@IBM.COM
T.J.Watson Research Center
Yorktown Heights, N.Y. 10598
∂16-Dec-88 1258 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Dec 88 12:58:23 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA16953; Fri, 16 Dec 88 13:57:17 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05870; Fri, 16 Dec 88 13:57:13 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812162057.AA05870@defun.utah.edu>
Date: Fri, 16 Dec 88 13:57:11 MST
Subject: issue COMPILER-DIAGNOSTICS, version 7
To: cl-compiler@sail.stanford.edu
Dan and I have been trading messages furiously on this issue for the
past few days, and we think we've finally come up with an acceptable
writeup. The major changes since version 4 are that the NOTICE
condition is now fully specified, and an example has been added.
There have also been some changes to the wording; namely, what used to
be referred to as an "error handler" is now referred to as a
"condition handler" to make it clear that it can intercept all kinds
of conditions, not just errors.
-Sandra
Issue: COMPILER-DIAGNOSTICS
References: CLtL p. 438-439, 62, 69, 160, 161
Condition System, Revision #18
S:>KMP>cl-conditions.text.34
Issue GC-MESSAGES
Issue RETURN-VALUES-UNSPECIFIED
Issue COMPILER-VERBOSITY
Category: CLARIFICATION, ENHANCEMENT
Edit History: V1, 15 Oct 1988, Sandra Loosemore
V2, 19 Oct 1988, Sandra Loosemore (minor fixes)
V3, 25 Oct 1988, Sandra Loosemore (input from Pitman & Gray)
V4, 01 Nov 1988, Sandra Loosemore (fix typos)
V5, 15 Dec 1988, Dan L. Pierson (new condition types)
V6, 15 Dec 1988, Sandra Loosemore (additions, fix wording)
V7, 16 Dec 1988, Dan L. Pierson (minor cleanup)
Problem Description:
It is unclear whether various diagnostics issued by the compiler are
supposed to be true errors and warnings, or merely messages.
In some implementations, COMPILE-FILE handles even serious error
situations (such as syntax errors) by printing a message and then
trying to recover and continue compiling the rest of the file, rather
than by signalling an error. While this user interface style is just
as acceptable as invoking the debugger, it means that a normal return
from COMPILE-FILE does not necessarily imply that the file was
successfully compiled.
Many compilers issue warnings about programming style issues (such as
binding a variable that is never used but not declared IGNORE).
Sometimes these messages obscure warnings about more serious problems,
and there should be some way to differentiate between the two. For
example, it should be possible to suppress the style warnings.
Also, neither CLtL nor issue RETURN-VALUES-UNSPECIFIED states what the
return value from COMPILE-FILE should be.
Proposal COMPILER-DIAGNOSTICS:USE-HANDLER:
(1) Add the following to the language:
NOTICE [Type]
The notice type is a subtype of CONDITION, disjoint from
WARNING, SEVERE-CONDITION, and SIMPLE-CONDITION. All types of
notices should inherit from this type.
SIMPLE-NOTICE [Type]
Conditions signalled by NOTICE when given a format string as a
first argument are of this type. This is a subtype of NOTICE,
and in implementations supporting multiple inheritance, this
type will also be a subtype of SIMPLE-CONDITION. The init
keywords :FORMAT-STRING and :FORMAT-ARGUMENTS are supported to
initialize the slots, which can be accessed using
SIMPLE-CONDITION-FORMAT-STRING and SIMPLE-CONDITION-FORMAT-ARGUMENTS.
ALERT [Type]
This is a subtype of NOTICE.
NOTICE datum &rest arguments [Function]
This function signals a condition of type NOTICE. The arguments
are interpreted similarly to those for the function WARN; if the
"datum" is a string, then a condition of type SIMPLE-NOTICE will
be signalled.
While the NOTICE is being signalled, this function establishes
the MUFFLE-NOTICE restart for use by a handler to cause the NOTICE
function to return immediately without further action. If no
handlers for the notice condition are found, or if all such
handlers decline, then the condition will be reported to
*ERROR-OUTPUT*.
The value returned by NOTICE is NIL.
MUFFLE-NOTICE [Function]
This function transfers control to the restart named MUFFLE-NOTICE.
If no such restart exists, MUFFLE-NOTICE signals an error of type
CONTROL-ERROR.
(2) Clarify that ERROR, WARNING, and ALERT conditions may be signalled
within COMPILE or COMPILE-FILE, including arbitrary errors which may
occur due to compile-time processing of (EVAL-WHEN (COMPILE) ...)
forms or macro expansion.
Considering only those conditions signalled -by- the compiler (as
opposed to -within- the compiler),
(a) Conditions of type ERROR may be signalled by the compiler in
situations where the compilation cannot proceed without
intervention.
Examples:
file open errors
syntax errors
(b) Conditions of type WARNING may be signalled by the compiler in
situations where the standard explicitly states that a warning must,
should, or may be signalled; and where the compiler can determine
that a situation that "is an error" would result at runtime.
Examples:
violation of type declarations
SETQ'ing or rebinding a constant defined with DEFCONSTANT
calls to built-in Lisp functions with wrong number of arguments
or malformed keyword argument lists
referencing a variable declared IGNORE
unrecognized declaration specifiers
(c) All other diagnostics issued by the compiler should be conditions
of type ALERT. In particular, this category includes all
diagnostics about matters of programming style. Although
conditions of type ALERT -may- be signalled in these
situations, no implementation is -required- to do so.
However, if an implementation does choose to signal a
condition, that condition will be of type ALERT and will be
signalled by a call to the function NOTICE.
Examples:
redefinition of function with different argument list
unreferenced local variables not declared IGNORE
declaration specifiers described in CLtL but ignored by
the compiler
(3) Require COMPILE-FILE to establish a condition handler. Add a
:HANDLER keyword argument to COMPILE-FILE, which is a user condition
handler function which is to be used during compilation. If the user
handler is not supplied or declines to handle a condition, then the
compiler's default handler will be invoked. Require the compiler
to handle the ABORT restart by aborting the smallest feasible part
of the compilation.
(4) Specify that COMPILE-FILE returns three values. The first value is the
truename of the output file, or NIL if the file could not be created.
The second value is non-NIL if errors were signalled during compilation
that were not handled by the user condition handler (indicating that
the output file is almost certainly unusable). The third value is
non-NIL if warnings were signalled during compilation that were not
handled by the user condition handler (indicating that the output
file may or may not be usable).
(5) Clarify that COMPILE does not establish a condition handler. Instead,
it uses whatever condition handler has been established in the environment
from which it is called.
Rationale:
Point by point,
(1) The new condition types NOTICE and ALERT are structured to allow
this part of the condition hierarchy to be further extended. In
particular, the issue COMPILER-VERBOSITY proposes an additional
subtype of NOTICE named INFO. The description of the NOTICE
function parallels the behavior of WARN.
(2) Conditions such as syntax errors which are errors in the interpreter
remain errors in the compiler. The division of other conditions
into WARNINGs and ALERTs allows potentially serious problems to be
distinguished from mere kibbitzing on the part of the compiler.
(3) It is reasonable for the default handling of compiler errors not to
cause the debugger to be invoked. However, any condition handler
established by COMPILE-FILE would override handlers established by the
user in the surrounding environment.
Requiring the compiler to handle the ABORT restart reflects what
several implementations already do (although probably not using this
mechanism). The intent of the wording is to allow an implementation
to abort the entire file compilation if it is not feasible to abort a
smaller part.
(4) This allows users to determine whether or not COMPILE-FILE is able to
actually compile the file successfully. Returning several values is
is more useful than a single success/failure value because there are
several degrees of failure.
(5) This is to reflect the use of COMPILE-FILE as being more "batch"-oriented
and COMPILE as being more interactive. There is less motivation to have
COMPILE try to recover from errors without user interaction.
Test Case/Example:
An example to illustrate how COMPILE-FILE should set up its condition
handlers is:
(defvar *output-file-truename* nil)
(defvar *errors-detected* nil)
(defvar *warnings-detected* nil)
;;; Call INTERNAL-COMPILE-FILE to do the real work. Note, that function
;;; may set up additional ABORT restarts.
(defun compile-file (input-file &key output-file handler)
(let ((*output-file-truename* nil)
(*errors-detected* nil)
(*warnings-detected* nil))
(with-simple-restart (abort "Abort compilation.")
(handler-bind ((condition #'compile-file-default-handler))
(if handler
(handler-bind ((condition handler))
(internal-compile-file input-file output-file))
(internal-compile-file input-file output-file))))
(values *output-file-truename*
*errors-detected*
*warnings-detected*)))
;;; The default condition handler keeps track of errors and warnings,
;;; and may also perform other implementation-specific actions.
(defun compile-file-default-handler (condition)
(typecase condition
(error
(setq *errors-detected* t)
...)
(warning
(setq *warnings-detected* t)
...)
(alert
...)
))
Current Practice:
No implementation behaves exactly as specified in this proposal.
In VaxLisp, COMPILE-FILE handles most compile-time errors without
invoking the debugger. (It gives up on that top-level form and moves on
to the next one.) Instead of signalling errors or warnings, it simply
prints them out as messages.
In Lucid Common Lisp, COMPILE-FILE invokes the debugger when it encounters
serious problems. COMPILE-FILE returns the pathname for the output file.
Symbolics Genera usually tries to keep compiling when it encounters errors;
so does Symbolics Cloe.
On the TI Explorer, the compiler tries to catch most errors and turn
them into warnings (except for errors on opening a file), but the user
can change special variable COMPILER:WARN-ON-ERRORS to NIL if he wants
to enter the debugger on an error signalled during reading, macro
expansion, or compile-time evaluation. The true name of the output
file is returned as the first value. A second value indicates whether
any errors or warnings were reported.
Cost to implementors:
The cost to implementors is not trivial but not particularly high. This
proposal tries to allow implementations considerable freedom in what
kinds of conditions the compiler must detect and how they are handled,
while still allowing users some reasonably portable ways to deal with
compile-time errors.
Cost to users:
This is a compatible extension. This proposal may cause users to see
some small differences in the user interface to the compiler, but
implementations already vary quite widely in their approaches. Some
users will probably have to make some minor changes to their code.
Adding the new functions and types may cause conflicts with user code
already using those names.
Benefits:
Users are given a way to detect and handle compilation errors, which
would simplify the implementation of portable code-maintenance
utilities. The behavior of the compiler in error situations is made
more uniform across implementations.
Discussion:
The issue of whether the compiler may print normal progress messages
is discussed in detail in a separate issue, COMPILER-VERBOSITY.
We contemplated making the NOTICE condition be a subtype of WARNING
instead of introducing a parallel set of types and functions. It was
thought that some possible uses of NOTICEs would not justify being
classified as warnings (although it would not be totally unreasonable
for the purposes of this proposal to classify ALERT under WARNING
instead of NOTICE). We also contemplated using the name MESSAGE
instead of NOTICE, but it was felt that NOTICE would be less likely to
cause conflicts with existing user code.
Pitman says that he would like to require COMPILE-FILE's default
condition handler never to invoke the debugger. I have left that out
of this proposal because it seems like an unnecessary restriction; if
users want to ensure that kind of behavior it is possible to do so by
supplying a user handler. (Of course, the converse is also true.)
Some of the things specified in section 2c as being ALERTS were
described in CLtL as being WARNINGs. There seems to be general
agreement that these things (particularly complaints about unused
variables) are not as serious as other problems described as warnings.
We might consider introducing a COMPILER-CONDITION that can be used in
mixins with the other condition types, so that error handlers can
distinguish between errors signalled by the compiler itself and errors
signalled during macroexpansion or EVAL-WHEN processing. This would
have to wait until the condition system is fully CLOSified.
Gray would like to exclude errors resulting from failure to open the
input and output files from the compiler's error handling. He also
suggests that the :HANDLER keyword argument be renamed :ERROR-HANDLER.
Some might wonder why NOTICE is needed instead of just making ALERT a
subtype of WARNING. This is for compatability with other proposed
conditions, notably INFO. While it might be reasonable to say that a
style "warning" is a legitimate WARNING error message, it is really
hard to justify WARNING status for a message like
;;; Starting to compile file foo.
Possibly NOTICE should write to *STANDARD-OUTPUT* rather than
*ERROR-OUTPUT*.
The initial names were MESSAGE and NOTICE, instead of NOTICE and
ALERT. They were changed in hopes of breaking fewer user function
definitions. Suggestions for better names are welcome.
-------
∂16-Dec-88 1433 CL-Compiler-mailer issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Dec 88 14:33:06 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA19823; Fri, 16 Dec 88 15:32:14 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05921; Fri, 16 Dec 88 15:32:11 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812162232.AA05921@defun.utah.edu>
Date: Fri, 16 Dec 88 15:32:10 MST
Subject: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
To: cl-compiler@sail.stanford.edu
I still haven't heard from the CLOS people yet, but I thought I should
circulate this version anyway so that all of you will have more time
to comment on the changes made so far.
Following a suggestion made by Pitman, I have revised the wording to
make it more explicitly clear which things are requirements for users
and which things are requirements for implementators. I have also
indicated that some of the requirements for users hold only if the
thing that is being defined is actually referenced in the file being
compiled.
The other major change here is the treatment of DEFCONSTANT. The
wording in this version is rather vague, but it's intended to
legitimize all of the various alternative behaviors that have been
suggested. I don't think any implementation is not in conformance
with what I've described.
Issue: COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
References: CLtL pages 66-70, 143
Category: CLARIFICATION
Edit history: V1, 07 Oct 1987 Sandra Loosemore
V2, 15 Oct 1987 Sandra Loosemore
V3, 15 Jan 1988 Sandra Loosemore
V4, 06 May 1988 Sandra Loosemore
V5, 20 May 1988 Sandra Loosemore
V6, 09 Jun 1988 Sandra Loosemore
V7, 16 Dec 1988 Sandra Loosemore
(Comments from Pitman, change DEFCONSTANT, etc.)
Problem Description:
Standard programming practices assume that, when calls to defining
macros such as DEFMACRO and DEFVAR are processed by COMPILE-FILE,
certain side-effects occur that affect how subsequent forms in the
file are compiled. However, these side-effects are not mentioned in
CLtL, except for a passing mention that macro definitions must be
``seen'' by the compiler before it can compile calls to those macros
correctly. In order to write portable programs, users must know
exactly which defining macros have compile-time side-effects and what
those side-effects are.
Inter-file compilation dependencies are distinct from, and not
addressed by, this issue.
Proposal: COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY
(1) Clarify that defining macros such as DEFMACRO or DEFVAR, appearing
within a file being processed by COMPILE-FILE, normally have
compile-time side effects which affect how subsequent forms in the
same file are compiled. A convenient model for explaining how these
side effects happen is that the defining macro expands into one or
more EVAL-WHEN forms, and that the calls which cause the compile-time
side effects to happen appear in the body of an (EVAL-WHEN (COMPILE)
...) form.
(2) The affected defining macros and their specific side effects are
as follows. In each case, it is identified what users must do to
ensure that their programs are conforming, and what compilers must do
in order to correctly process a conforming program.
DEFTYPE: Users must ensure that the body of a DEFTYPE form is
evaluable at compile time if the type is referenced in subsequent type
declarations. The compiler must ensure that the DEFTYPE'd type
specifier is recognized in subsequent type declarations. If the
expansion of a type specifier is not defined fully at compile time
(perhaps because it expands into an unknown type specifier or a
SATISFIES of a named function that isn't defined in the compile-time
environment), an implementation may ignore any references to this type
in declarations and/or signal a warning.
DEFMACRO, DEFINE-MODIFY-MACRO: The compiler must store macro
definitions at compile time, so that occurrences of the macro later on
in the file can be expanded correctly. Users must ensure that the
body of the macro is evaluable at compile time if it is referenced
within the file being compiled.
DEFUN: DEFUN is not required to perform any compile-time side effects.
In particular, DEFUN does not make the function definition available
at compile time. An implementation may choose to store information
about the function for the purposes of compile-time error-checking
(such as checking the number of arguments on calls), or to enable the
function to be expanded inline.
DEFVAR, DEFPARAMETER: The compiler must recognize that the variables
named by these forms have been proclaimed special. However, the it
must not evaluate the initial value or SETQ the variable at compile
time.
DEFCONSTANT: The compiler must recognize that the symbol names a
constant. An implementation may choose to evaluate the value-form at
compile time, load time, or both. Therefore users must ensure that
the value-form is evaluable at compile time (regardless of whether or
not references to the constant appear in the file) and that it always
evaluates to the same value.
DEFSETF, DEFINE-SETF-METHOD: The compiler must make SETF methods
available so that it may be used to expand calls to SETF later on in
the file. Users must ensure that the body of DEFINE-SETF-METHOD and
the complex form of DEFSETF are evaluable at compile time if the
corresponding place is referred to in a subsequent SETF in the same
file.
DEFSTRUCT: The compiler must make the structure type name recognized
as a valid type name in subsequent declarations (as for DEFTYPE) and
make the structure slot accessors known to SETF. In addition, the
compiler must save enough information about the structure type so that
further DEFSTRUCT definitions can :INCLUDE a structure type defined
earlier in the file being compiled. The functions which DEFSTRUCT
generates are not defined at compile time. The #S reader syntax may
or may not be available at compile time.
DEFINE-CONDITION: The rules are essentially the same as those for
DEFSTRUCT; the compiler must make the condition type recognizable as a
valid type name, and it must be possible to reference the condition
type as the parent-type of another condition type in a subsequent
DEFINE-CONDITION in the file being compiled.
DEFCLASS, DEFMETHOD, DEFGENERIC, DEFINE-METHOD-COMBINATION: More input
is needed from the CLOS committee to decide what to do with these
macros.
DEFPACKAGE: All of the actions normally performed by this macro at load
time must also be performed at compile time.
(3) The compile-time side effects may cause information about the
definition to be stored differently than if the defining macro had
been processed in the "normal" way (either interpretively or by loading
the compiled file).
In particular, the information stored by the defining macros at
compile time may or may not be available to the interpreter (either
during or after compilation), or during subsequent calls to COMPILE or
COMPILE-FILE. For example, the following code is nonportable because
it assumes that the compiler stores the macro definition of FOO where
it is available to the interpreter:
(defmacro foo (x) `(car ,x))
(eval-when (eval compile load)
(print (foo '(a b c))))
A portable way to do the same thing would be to include the macro
definition inside the EVAL-WHEN:
(eval-when (eval compile load)
(defmacro foo (x) `(car ,x))
(print (foo '(a b c))))
Rationale:
The proposal generally reflects standard programming practices. The
primary purpose of the proposal is to make an explicit statement that
CL supports the behavior that most programmers expect and many
implementations already provide.
The primary point of controversy on this issue has been the treatment
of the initial value form by DEFCONSTANT, where there is considerable
variance between implementations. The effect of the current wording is
to legitimize all of the variants.
Current Practice:
Many (probably most) Common Lisp implementations, including VaxLisp
and Lucid Lisp, are already largely in conformance.
In VaxLisp, macro definitions that occur as a side effect of compiling
a DEFMACRO form are available to the compiler (even on subsequent
calls to COMPILE or COMPILE-FILE), but are not available to the
interpreter (even within the file being compiled).
By default, Kyoto Common Lisp evaluates *all* top level forms as they
are compiled, which is clearly in violation of the behavior specified
on p 69-70 of CLtL. There is a flag to disable the compile-time
evaluation, but then macros such as DEFMACRO, DEFVAR, etc. do not make
their definitions available at compile-time either.
Cost to implementors:
The intent of the proposal is specifically not to require the compiler
to have special knowledge about each of these macros. In
implementations whose compilers do not treat these macros as special
forms, it should be fairly straightforward to use EVAL-WHENs in their
expansions to obtain the desired compile-time side effects.
Cost to users:
Since CLtL does not specify whether and what compile-time side-effects
happen, any user code which relies on them is, strictly speaking,
nonportable. In practice, however, most programmers already expect
most of the behavior described in this proposal and will not find it
to be an incompatible change.
Benefits:
Adoption of the proposal will provide more definite guidelines on how
to write programs that will compile correctly under all CL
implementations.
Discussion:
Reaction to a preliminary version of this proposal on the common-lisp
mailing list was overwhelmingly positive. More than one person
responded with comments to the effect of "but doesn't CLtL already
*say* that somewhere?!?" Others have since expressed a more lukewarm
approval.
It has been suggested that this proposal should also include PROCLAIM.
However, since PROCLAIM is not a macro, its compile-time side effects
cannot be handled using the EVAL-WHEN mechanism. A separate proposal
seems more appropriate.
Item (3) allows for significant deviations between implementations.
While there is some sentiment to the effect that the compiler should
store definitions in a manner identical to that of the interpreter,
other people believe strongly that compiler side-effects should be
completely invisible to the interpreter. The author is of the opinion
that since this is a controversial issue, further attempts to restrict
this behavior should be considered as separate proposals.
It should be noted that user-written code-analysis programs must
generally treat these defining macros as special forms and perform
similar "compile-time" actions in order to correctly process
conforming programs.
-------
∂16-Dec-88 1547 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 7
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 16 Dec 88 15:47:05 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01642g; Fri, 16 Dec 88 15:44:13 PST
Received: by bhopal id AA22305g; Fri, 16 Dec 88 15:46:12 PST
Date: Fri, 16 Dec 88 15:46:12 PST
From: Jim McDonald <jlm@lucid.com>
Message-Id: <8812162346.AA22305@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Fri, 16 Dec 88 13:57:11 MST <8812162057.AA05870@defun.utah.edu>
Subject: issue COMPILER-DIAGNOSTICS, version 7
> Possibly NOTICE should write to *STANDARD-OUTPUT* rather than
> *ERROR-OUTPUT*.
Or to *TRACE-OUTPUT*, since notices are typically running commentary
of import similar to "Entering FOO", "Leaving FOO", etc.
jlm
∂16-Dec-88 1617 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Dec 88 16:17:23 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA22442; Fri, 16 Dec 88 17:16:33 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05978; Fri, 16 Dec 88 17:16:30 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812170016.AA05978@defun.utah.edu>
Date: Fri, 16 Dec 88 17:16:28 MST
Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 2
To: cl-compiler@sail.stanford.edu
Here's a first cut at the new proposal. Comments, flames, etc. are welcome.
Issue: EVAL-WHEN-NON-TOP-LEVEL
References: CLtL p. 69-70
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CHANGE, CLARIFICATION
Edit History: 6-May-88, V1 by Sandra Loosemore
16 Dec 1988, V2 by Sandra Loosemore (alternate direction)
Problem Description:
The current description of how the compiler should handle EVAL-WHEN
only makes sense when it appears as a top-level form in the file being
compiled. Is it legitimate for EVAL-WHEN to appear in non-top-level
locations? What does it mean in such places?
Proposal EVAL-WHEN-NON-TOP-LEVEL:IGNORE-COMPILE:
Clarify that EVAL-WHEN may appear both at top-level and at
non-top-level. In non-top-level locations, however, the COMPILE
situation is effectively ignored.
More specifically, when an EVAL-WHEN form is processed by the
interpreter (that is, by the function EVAL), the presence of the EVAL
situation indicates that the body of the EVAL-WHEN should be evaluated
as an implicit PROGN. Otherwise, EVAL-WHEN returns NIL without
evaluating the body.
When an EVAL-WHEN form is processed by the compiler:
(1) If the situation COMPILE is specified:
- If the EVAL-WHEN form appears at top level, then each of the
forms within the body of the EVAL-WHEN are evaluated by the
compiler in the null lexical environment using the function
EVAL.
- Otherwise, no compile-time evaluation takes place. An
implementation is permitted to signal a warning to indicate
that the compile-time evaluation is being ignored.
(2) If the situation LOAD is specified, then the compiler treats
the body of the EVAL-WHEN form as if it were an implicit PROGN.
If the situation LOAD is not specified, then the compiler should
treat the EVAL-WHEN form as if it were a constant value of NIL.
Rationale:
Restricting compile-time evaluation to top-level locations prevents
complications resulting from performing the evaluation in the wrong
lexical environment.
The behavior specified for top-level EVAL-WHENs in this proposal
differs slightly from that described in CLtL. In the case where both
COMPILE and LOAD are specified, CLtL indicates that the compile-time
evaluation should be interleaved with normal compiler processing of
each of the forms in the body, while this proposal specifies that the
evaluation of all of the body forms should take place before any of
the normal compiler processing (leading to possible multiple
evaluations in the case of nested EVAL-WHENs). However, it is
unlikely that this would cause serious problems for any user programs.
The nesting behavior of EVAL-WHEN as described in CLtL has been
criticized as overly complicated and hard to understand, while this
proposal is much less complicated.
Allowing implementations to signal a warning when ignoring a
non-top-level EVAL-WHEN allows users to be informed that something
unusual is going on.
Current Practice:
IIM Common Lisp implements this proposal. Kim Barrett contributed the
following code that illustrates their implementation:
(defmacro eval-when (situations &body body &environment env)
(if (not (compiler-environment-p env))
(when (member 'eval situations) `(progn ,@body))
(progn
(when (member 'compile situations)
(if (compiler-at-top-level-p env)
(mapc #'eval body)
(warn "Top-level form encountered at non-top-level.")))
(when (member 'load situations) `(progn ,@body)))))
Cost to implementors:
Probably fairly minor in most implementations.
Cost to users:
Except for the change relating to possible multiple evaluation of
nested EVAL-WHENs, this proposal is a compatible extension.
Benefits:
The behavior of EVAL-WHEN is easier to understand. Making EVAL-WHEN
meaningful at non-top-level locations makes it more generally useful,
for example in the expansion of defining macros.
Discussion:
Proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW provides a definition for
the term "top-level".
-------
∂16-Dec-88 1620 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Dec 88 16:19:33 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA22466; Fri, 16 Dec 88 17:18:38 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05990; Fri, 16 Dec 88 17:18:36 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812170018.AA05990@defun.utah.edu>
Date: Fri, 16 Dec 88 17:18:34 MST
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 5
To: cl-compiler@sail.stanford.edu
Here's a revised proposal on this issue for your entertainment.
Issue: DEFINING-MACROS-NON-TOP-LEVEL
References: CLtL p. 66-70, 143
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue COMPILER-LET-CONFUSION
Category: CLARIFICATION, ENHANCEMENT
Edit History: 6-May-88, V1 by Sandra Loosemore
9-Jun-88, V2 by Sandra Loosemore
12-Sep-88, V3 by Sandra Loosemore (fix garbled section 4)
21-Sep-88, V4 by Sandra Loosemore (clarify section 5)
16-Dec-88, V5 by Sandra Loosemore (major restructuring)
Problem Description:
CLtL leaves the interpretation of defining forms such as DEFMACRO and
DEFVAR that appear in other than top-level locations unclear.
On page 66, it is stated: "It is not illegal to use these forms at
other than top level, but whether it is meaningful to do so depends on
context. Compilers, for example, may not recognize these forms
properly in other than top-level contexts". At least one implementation
has interpreted this to mean that it is permissible to simply refuse
to compile defining macros that do not appear at top-level.
Proposal: DEFINING-MACROS-NON-TOP-LEVEL:ALLOW
(1) Remove the language from p. 66 of CLtL quoted above. Clarify that
while defining macros normally appear at top level, it is meaningful
to place them in non-top-level contexts and that the compiler must
handle them properly in all situations. However, the compile-time side
effects described in issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
only take place when the defining macros appear at top-level.
(2) Remove the language on p. 145 of CLtL, which states that macro
functions are always defined in the null lexical environment. Clarify
that all defining macros which create functional objects (including
DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
DEFSETF, as well as DEFUN) must ensure that those functions are
defined in the lexical environment in which the defining macro is
executed.
(3) Clarify that ``top-level forms'' are evaluable data objects read
in from an input source (such as a keyboard or disk file) by
successive calls to the function READ; these forms would be evaluated
by the interpreter in a null lexical environment. As special cases,
forms within a top-level PROGN, EVAL-WHEN, or COMPILER-LET are also
considered to be top-level forms, as is the expansion of a macro call
appearing at top-level. Specify that top-level forms in a file being
compiled are guaranteed to be processed sequentially, but the order in
which subforms of a top-level form are processed by the compiler is
explicitly left unspecified.
Rationale:
The notion of a ``top-level form'' is rather confused, since the term
is used in CLtL to refer both to a place where a form may appear (what
this proposal continues to call ``top-level''), and to instances of
forms which traditionally appear there (what this proposal calls
``defining macros'').
There has been a suggestion that the notion of a top-level form should
be extended to include forms in the body of a top-level LET, to allow
forms such as DEFUN to be meaningful there. However, we feel that a
cleaner solution is to remove the restrictions on the placement of
defining macros altogether.
Current Practice:
CLtL mentions only that forms within a top-level PROGN, and not
COMPILER-LET, are treated as top-level. However, COMPILER-LET is
also treated specially in implementations derived from the MIT Lisp
Machine (TI and Symbolics), as well as Lucid and Coral (but not
VaxLisp).
Cost to implementors:
Implementations that currently don't compile defining macros correctly
when they appear at non-top-level will have to be changed.
Cost to users:
None. This is a compatible extension.
Benefits:
The notion of defining macros as being somehow special when they
appear at top-level is removed. Allowing defining macros to appear
anywhere instead of restricting them to certain positions results in a
cleaner language design.
Discussion:
This proposal is consistent with the behavior specified in proposal
EVAL-WHEN-NON-TOP-LEVEL:IGNORE-COMPILE. In particular, if the compile
time side-effects for defining macros specified in proposal
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY are implemented using
EVAL-WHEN, the "right" compiler behavior for defining macros at
non-top-level will happen automatically.
-------
∂17-Dec-88 1339 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 17 Dec 88 13:38:45 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa05163; 17 Dec 88 20:53 GMT
Date: Sat, 17 Dec 88 21:05:48 GMT
Message-Id: <9379.8812172105@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Jon L White <@sail.stanford.edu:jonl@lucid.com>, cperdue@sun.com
In-Reply-To: Jon L White's message of Fri, 16 Dec 88 01:40:26 PST
Cc: sandra <@cs.utah.edu:sandra@defun>, cl-compiler@sail.stanford.edu
> re: I claim that the apparent copying "isn't QUOTE's fault", and that
> it happens regardless of the semantics of quote.
>
> Interesting "gedanken" experiment. In upshot, however, it seems that
> you are _supporting_ the semantics of "QUOTE may copy", right? Because,
> as you say, there are situations wherein one can't avoid it regardless
> of how one implements quote
I'm inclined to agee with Chris's analysis. I also thought something
similar might be done for coalescing, since it's READ or LAOD that
constructs the objects.
I think the point of this approach is to make the copying part of
file compilation so that it doesn't backup into the semantics of QUOTE
in interpreted and COMPILE'd code. I'm not entirely sure that the
trick works.
∂17-Dec-88 1359 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 17 Dec 88 13:59:19 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA08505; Sat, 17 Dec 88 14:58:18 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06551; Sat, 17 Dec 88 14:58:06 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812172158.AA06551@defun.utah.edu>
Date: Sat, 17 Dec 88 14:58:05 MST
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: Jon L White <@sail.stanford.edu:jonl@lucid.com>, cperdue@sun.com,
sandra <sandra%defun@cs.utah.edu>, cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Sat, 17 Dec 88 21:05:48 GMT
I'm not real sure if this line of thought is turning out to be
particularly productive. To me it seems pretty clear that any copying
of constants that goes on happens as a result of transforming an
arbitrary data structure into a program. In other words, the list
(defun foo () '(a b c))
is just a list. It doesn't become a program until it is passed to
EVAL or COMPILE or if it appears in a file being compiled with
COMPILE-FILE. The question we are trying to resolve is whether pieces
of the data structure that represent constant objects must appear
literally in the resulting program, or whether the transformation may
construct a equivalent copies instead.
Perhaps I chose a misleading name for this issue. I don't think
anybody is arguing that QUOTE itself must do whatever copying is
allowed. We could rename the issue to something less confusing, if
anybody has a suggestion.
-Sandra
-------
∂17-Dec-88 1718 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 17 Dec 88 17:16:25 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa00371; 18 Dec 88 0:55 GMT
Date: Sun, 18 Dec 88 01:08:17 GMT
Message-Id: <9851.8812180108@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: sandra <@cs.utah.edu:sandra@defun>, cl-compiler@sail.stanford.edu
> I'm not real sure if this line of thought is turning out to be
> particularly productive. To me it seems pretty clear that any copying
> of constants that goes on happens as a result of transforming an
> arbitrary data structure into a program.
Why are the constants transformed at all? I can see why the
program text (i.e., the list) might be transformed. The compiler
might compile it, the interpreter might macroexpand it or partially
compile it. But, unless some writing to a file is involved, why
would any processing be done to the constants?
> In other words, the list
>
> (defun foo () '(a b c))
>
> is just a list. It doesn't become a program until it is passed to
> EVAL or COMPILE or if it appears in a file being compiled with
> COMPILE-FILE. The question we are trying to resolve is whether pieces
> of the data structure that represent constant objects must appear
> literally in the resulting program, or whether the transformation may
> construct a equivalent copies instead.
If that DEFUN appears in a file, it's not a list yet. READ makes it
a list. COMPILE-FILE emits something that causes an (A B C) to be
made when the compiled file is loaded. That list isn't a list until
it's made. The COMPILE-FILE/LOAD process, like PRINT/READ, returns
an equivalent structure rather than the very same one. So that's
sort of like copying, but there's always a file operation involved.
Lists don't get copied once they're lists.
Chris's model suggests that the question is whether, for consistency,
some copying must be allowed even when no file operations are involved
(or, rather, after they've all been done). When we were talking in
terms of what QUOTE did, QUOTE often acted as a bridge for file
compilation semantics to cross over into EVAL and COMPILE. But maybe
it's possible to think in another way so that notion of consistency
doesn't seem so compelling.
You are now suggesting that we consider the point at which something
becomes a program. That is more or less equivaplent to pretending
that the expression always comes from a file. The question is
whether that's the only consistent way to think.
> Perhaps I chose a misleading name for this issue. I don't think
> anybody is arguing that QUOTE itself must do whatever copying is
> allowed.
There have certainly been messages that suggested that QUOTE might
return a (possibly read-only) copy. More recently, the idea that
QUOTE might copy once has appeared. That would correspond to your
idea that EVAL causes a list to become a program.
BTW, it is possible to ensure that only one copy is done?
∂17-Dec-88 2029 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 17 Dec 88 20:29:29 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA12653; Sat, 17 Dec 88 21:28:16 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06684; Sat, 17 Dec 88 21:28:02 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812180428.AA06684@defun.utah.edu>
Date: Sat, 17 Dec 88 21:28:01 MST
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: sandra <sandra%defun@cs.utah.edu>, cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Sun, 18 Dec 88 01:08:17 GMT
> More recently, the idea that
> QUOTE might copy once has appeared. That would correspond to your
> idea that EVAL causes a list to become a program.
Right.
> BTW, it is possible to ensure that only one copy is done?
I don't think see any problems with implementing the behavior
described in the current version of the proposal. We talked about the
implications of "only once" some time ago in relation to issue
LOAD-TIME-EVAL. I'm convinced that any copying would have to be done
by a preprocessor, but remember that in this case an implementation is
always free *not* to copy at all. There don't appear to be any
existing implementations that would be affected anyway.
Like I said before, this line of discussion does not really seem to be
getting us anywhere -- in particular, it doesn't seem like we are any
closer to a consensus. Earlier today I went through the back mail on
this issue since the latest version of the proposal was sent out, and
found that there was not really much substance arising out of it that
I could incorporate into the next revision of the writeup. Dan
Pierson has asked if we could assemble some -concise- summaries of the
arguments on all sides to include in the discussion section of the
writeup, and seeing as we only have a few days left now, I humbly
suggest we concentrate on getting the writeup in shape instead of
engaging in more drawn-out religious wars.
-Sandra
-------
∂18-Dec-88 2106 CL-Compiler-mailer Re: quoted constants
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 18 Dec 88 21:06:50 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA02209; Sun, 18 Dec 88 21:08:16 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA09647; Sun, 18 Dec 88 16:05:21 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA18861; Sun, 18 Dec 88 16:06:20 PST
Date: Sun, 18 Dec 88 16:06:20 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8812190006.AA18861@clam.sun.com>
To: DALY@ibm.com, cl-compiler@sail.stanford.edu
Subject: Re: quoted constants
Could you talk to the IBM representatives to X3J13 about this
concern of yours and designate someone from IBM who will be
in charge of the issue of Common Lisp quoted constants for IBM?
This person must be prepared to take time to understand the different
issues and something of what practice in the area has been.
If at all possible, the same person should also be able to attend
the in-person compiler committee meetings that occur as part of X3J13.
I see that Thom Linden is registered for the Hawaii meetings. Perhaps
it is just saying the obvious to suggest that you talk to Mark
Wegman about this also.
This is a pretty hard issue, and it has a whole collection of parts
that each have some degree of controversy attached, and that is why
it would be best if someone from IBM can really be the "point person"
on this entire issue and understand it as well as possible.
Designate a person and I will try to make sure I cc that person
on mail I send on the subject, including proposals, and I assume
that others will do likewise. It's just
too hard to discuss subtopics individually with people who
inquire about part of the issue.
-Cris
∂20-Dec-88 1212 CL-Compiler-mailer Re: issue COMPILER-DIAGNOSTICS, version 7
Received: from ti.com by SAIL.Stanford.EDU with TCP; 20 Dec 88 12:11:42 PST
Received: by ti.com id AA00870; Tue, 20 Dec 88 14:09:06 CST
Received: from Kelvin by tilde id AA06079; Mon, 19 Dec 88 11:44:44 CST
Message-Id: <2807545491-1672926@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 19 Dec 88 11:44:51 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue COMPILER-DIAGNOSTICS, version 7
In-Reply-To: Msg of Fri, 16 Dec 88 13:57:11 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Subject: issue COMPILER-DIAGNOSTICS, version 7
This proposal looks good, but there are a couple of little things worrying
me. One is the potentially confusing shift in terminology by which
compiler messages that are conventionally referred to as "warnings", are
now called "alerts", programmer errors are reported as "warnings", and
only what is conventionally called "fatal errors" are reported as "errors".
I don't know what can be done about this, though, since we do want some
down-grading in severity so that the compiler issues a message and continues
for a situation that will signal an error if the compiled code is run.
Probably we just need to be careful how this is documented in order to
minimize confusion.
Another thing is that this doesn't provide a way to suppress style
"warnings" [ALERT conditions] on a local basis. For example, Lisp
Machines have a macro INHIBIT-STYLE-WARNINGS that can be wrapped around a
single form to keep the compiler quiet. I wonder if we might want a
COMPILER-HANDLER-BIND macro for specifying handlers at compile time? This
would be analogous to COMPILER-LET, but it could avoid the problems that
have doomed COMPILER-LET by specifying that the evaluator is free to
ignore it.
> Gray ...
> suggests that the :HANDLER keyword argument be renamed :ERROR-HANDLER.
That was when I thought it would only be for ERROR conditions. Now that
the example shows doing
(handler-bind ((condition handler)) ...
the name :HANDLER is more appropriate, although it might be better to call
it :CONDITION-HANDLER.
∂20-Dec-88 1214 CL-Compiler-mailer Re: issue COMPILER-DIAGNOSTICS, version 7
Received: from ti.com by SAIL.Stanford.EDU with TCP; 20 Dec 88 12:14:21 PST
Received: by ti.com id AA00882; Tue, 20 Dec 88 14:09:21 CST
Received: from Kelvin by tilde id AA06403; Mon, 19 Dec 88 12:04:02 CST
Message-Id: <2807546657-1742991@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 19 Dec 88 12:04:17 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Jim McDonald <jlm@lucid.com>
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
Subject: Re: issue COMPILER-DIAGNOSTICS, version 7
In-Reply-To: Msg of Fri, 16 Dec 88 15:46:12 PST from Jim McDonald <jlm@lucid.com>
> > Possibly NOTICE should write to *STANDARD-OUTPUT* rather than
> > *ERROR-OUTPUT*.
>
> Or to *TRACE-OUTPUT*, since notices are typically running commentary
> of import similar to "Entering FOO", "Leaving FOO", etc.
Yes, you would like such INFO conditions reported on the terminal, but I
would like ALERT conditions [e.g. "style warnings"] to be able to be
included in a DRIBBLE file. This makes me wonder if the concept of
combining these under the NOTICE condition might not be such a good idea.
It also reminds me of a point I raised a long time ago, that DRIBBLE ought
to bind *ERROR-OUTPUT* as well as *STANDARD-OUTPUT*. I still think it is
important that we not require compiler error messages to be written in
such a way that they can't be captured in a dribble file.
∂20-Dec-88 1224 CL-Compiler-mailer Re: issue COMPILER-DIAGNOSTICS, version 7
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 20 Dec 88 12:24:07 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA23281; Tue, 20 Dec 88 15:22:41 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA06173; Tue, 20 Dec 88 15:22:38 EST
Message-Id: <8812202022.AA06173@mist.>
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue COMPILER-DIAGNOSTICS, version 7
In-Reply-To: Your message of Mon, 19 Dec 88 12:04:17 -0600.
<2807546657-1742991@Kelvin>
Date: Tue, 20 Dec 88 15:22:36 EST
From: Dan L. Pierson <pierson@mist.encore.com>
Yes, you would like such INFO conditions reported on the terminal, but I
would like ALERT conditions [e.g. "style warnings"] to be able to be
included in a DRIBBLE file. This makes me wonder if the concept of
combining these under the NOTICE condition might not be such a good idea.
It also reminds me of a point I raised a long time ago, that DRIBBLE ought
to bind *ERROR-OUTPUT* as well as *STANDARD-OUTPUT*. I still think it is
important that we not require compiler error messages to be written in
such a way that they can't be captured in a dribble file.
I agree. I lumped ALERT and NOTICE together to keep them from causing
BREAKs. While this is important, it is also important that it be
trivial for the user to route all compiler messages together and in
order to the same destination, whether it be a dribble file, a
separate compiler output window, or whatever.
∂20-Dec-88 1707 CL-Compiler-mailer CONSTANT-COMPILABLE-TYPES:SPECIFY, V4
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 20 Dec 88 17:07:23 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA08282; Tue, 20 Dec 88 17:08:15 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA23659; Tue, 20 Dec 88 17:04:50 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA22171; Tue, 20 Dec 88 17:05:48 PST
Date: Tue, 20 Dec 88 17:05:48 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8812210105.AA22171@clam.sun.com>
To: cl-compiler%clam@Sun.COM
Subject: CONSTANT-COMPILABLE-TYPES:SPECIFY, V4
Here at last is V4 of the proposal, much cleaned up I think from
before. I have attempted to respond to as many as possible of the
concerns, complaints, etc., about the previous version, so worry if
something really important to you is not fixed here.
The issue of potential immutability of constants has been removed from
this proposal. I have not yet finished reassembling that material into
another proposal, and expect to do so by the first of the year. I do
not intend to change it, just to split it out from this one.
---------------------------------------
Issue: CONSTANT-COMPILABLE-TYPES
References: CLtL pp. 56, 77-80, 324
Issue CONSTANT-MODIFICATION
Issue CONSTANT-CIRCULAR-COMPILATION
Issue CONSTANT-ARRAY-ATTRIBUTES
Category: CLARIFICATION, ADDITION
Edit history: 11/07/88, V1 by Cris Perdue
11/14/88, V2 by Cris Perdue
11/22/88, V3 by Cris Perdue
12/20/88, V4 by Cris Perdue
Status: DRAFT
Problem description:
CLtL does not specify what objects can be in compiled constants and it
does not say what relationship there can or must be between the
constant passed to the compiler and the one that is established by
compiling and then loading its file. Relevant remarks in CLtL
concerning file compilation and the definition of QUOTE suggest that
the compiler handles constants in ways that are not actually possible.
Introduction to the proposal:
The proposal CONSTANT-COMPILABLE-TYPES:SPECIFY attempts to spell out
what types can appear in compiled constants, and what it means when
they appear. Unless stated otherwise, in this proposal where the term
"constant" is used, it means a quoted constant, not a named
(defconstant) constant.
The key is a definition of a form of equivalence between Lisp objects,
"similarity as constants". Code passed through the file compiler must
behave as though quoted constants in it are equivalent to quoted
constants in the corresponding interpreted "source" code. This
proposal only concerns quoted constants to be processed by
COMPILE-FILE.
For the benefit of users, this proposal tries to define a fairly large
set of types that all Common Lisp implementations are to handle. It
also attempts to leave room for implementations to differ. Some
implementations have made opposing choices because the language
doesn't specify one over the other. Some implementations already
handle constants that this proposal defines as not legal in Common
Lisp programs, and that is useful to users of those systems.
Different implementors have different amounts of resources to apply to
their system, and implementations differ in their whole approach in
some cases.
We try to set up a framework where some controversies can be defined
clearly and resolved as separate issues.
One of these is the question of when, if ever, to permit "coalescing"
of constants. Some implementations already take advantage of the
license given on page 78 of CLtL to gain some efficiencies. This
proposal provides definitions that make it possible to broaden the
conditions where coalescing is permitted.
Another question is whether "circular" constants are compilable. Most
implementations are capable of supporting circular constants. Still, this
proposal avoids requiring all implementations to handle circular
constants. Implementations that do not handle circular constants
presumably also do not make sure that shared structure remains shared,
sort of the opposite of coalescing. This proposal avoids requiring
shared structure to remain shared across compilation.
Some implementations "lose information" about some constants during
compilation. We try to limit this proposal enough to reduce the
number of unhappy implementors to a bare minimum.
In this version, the question of immutability of some attributes of
objects in compiled constants is not addressed. Cris has taken that
material out of this proposal and is constructing a new proposal
covering just that issue. This proposal does define the concept of
"basic attributes" of various types of objects, and the other proposal
will refer to it, stating that most basic attributes of most types of
objects may be treated as immutable when the object appears in a
compiled constant.
Proposal: CONSTANT-COMPILABLE-TYPES:SPECIFY
An object may be used as a quoted constant processed by COMPILE-FILE
if the compiler can guarantee that the resulting constant established
by loading the compiled file is "similar as a constant" to the
original, plus a few other restrictions.
A few types, such as streams, are not supported in constants. In
other words, an object containing one of these is not considered
similar as a constant to any other object. We say that it is an error
for these objects to appear in a (compiled) constant. Still some
implementations may support them and define how they are treated.
Some types of objects are treated as aggregate objects. For these
types, being similar as constants is defined recursively. We say that
an object of these types has certain attributes, and to be similar as
a constant to another object, the values of the corresponding
attributes of the two objects must also be similar as constants.
This kind of definition has problems with circular or "infinitely
recursive" objects such as a list that is an element of itself. We
consider the idea of depth-limited comparison, and say that two
objects are similar as constants if they are similar at all finite
levels. This idea is implicit in the definitions below, and applies
in all the places where attributes of two objects are required to be
similar as constants.
The rest of this proposal consists of a definition of the notion of
two objects being "similar as constants", organized by type, with some
notes about the additional constraints that the compiler must meet:
Number, Character
If either of two objects is a number or character, the two objects
are similar as constants if and only if they are EQL.
(Note that for cross-compilers it is not always possible to satisfy
this requirement for floating point numbers and complex numbers with
floating point parts. If it is necessary to choose two different
floating point values due to cross-compilation, each value chosen must
be one of the two adjacent, exactly representable numbers such that
the interval between them contains the other number. Other numbers
and characters are represented exactly, so they can be compared if
they are representable on both architecture, an issue for some
characters.)
Random-state
Only the operations PRINT, MAKE-RANDOM, and RANDOM apply to
random-states. Let us say that two random-states are functionally
equivalent if applying RANDOM to them repeatedly always produces the
same pseudo-random numbers in the same order.
Two random-states are similar as constants exactly if copies of them
made via MAKE-RANDOM-STATE are functionally equivalent.
Symbol
A symbol can only be similar to a symbol. References to symbols are
permitted in any constant. References to interned symbols are "by
name". If the symbol is interned, its name and the name of its home
package identify it.
A symbol with a home package is similar as a constant to a symbol when
the names of the symbols and the names of the home packages of the
symbols are similar as constants. (Both symbols must have home
packages.) Within a Common Lisp "address space", this implies that
the symbols are EQ.
If a symbol is not interned, i.e. its home package is NIL, it is
treated in a rather special way. To be similar as a constant to
another symbol, both symbols must be uninterned and have the same
name.
Constants that contain uninterned symbols have to satisfy extra
constraints. If an uninterned symbol appears in a certain set of
places in one constant, it must appear in the same places in both
constants. If we consider the set of constants that appear in a file,
in its functions, top level forms, etc., the constants in the compiled
form of the file must be similar, all together, to the constants in
the source. It is as if there were a constant list with all the
file's constants as members. These conceptual lists for the source
and compiled versions of a file must be similar as constants.
Package
A package can only be similar as a constant to a package. References
to packages are permitted in any constant. References to packages are
"by name": two packages are similar as constants when their names are
similar as constants. Within a Lisp "address space", packages with
the same name are EQ.
At load time, the package becomes the same as returned by
FIND-PACKAGE, given the package name. An error is signalled if no
package of that name exists at load time.
OTHER TYPES
-----------
For each of the types listed below, if either object is of the given
type, the two objects are similar as constants exactly if the other is
of that type and the values of all of the specified attributes are
similar as constants.
The attributes listed here can be called the "Basic Attributes" of
objects of each of these types.
Cons CAR, CDR.
Array For 1-dimensional arrays:
LENGTH and ELT for all legal indices.
For arrays of other dimensions:
ARRAY-DIMENSIONS, ARRAY-ELEMENT-TYPE, AREF for all legal
indices.
Note that array constants in a compiled file may lack
displacement, fill pointers, or adjustability, where the
constants in the source had them, but the compiler may
not produce constant arrays that have these features from
ones that do not. The point is to make sure that
declarations are not violated as a result of compilation.
Structure Slot values, name of structure type (a symbol reference).
Hash-table Keys and values. The table's test is of course unchanged
also. It is an error to compile a constant containing a
a hash table that has keys that are similar as
constants.
Readtable Character syntax type for each character in the table;
function for each readmacro character, mappings for
dispatch macros; whether terminating or nonterminating
for each readmacro.
Pathname Each pathname component
Stream, Compiled-Function
It is an error for a stream or compiled-function
to appear in a compiled constant, but the
language may be extended in the future to support certain
cases.
Function Function constants that are not compiled-functions and do
not close over any (lexical) variables are permitted in
compiled constants. Two functions are similar as
constants when they are operationally equivalent. Use of
global function bindings, global macro bindings, and
special variables must be considered external
dependencies for this purpose, and constants appearing in
the functions need only be similar as constants (at level
n-1?).
Generic-function, Method
Help is needed from the CLOS committee to determine what
to do here.
Standard-object
Help is needed from the CLOS committee to determine what
do do here.
Rationale:
This proposal appears to reflect user demand and appears not to exceed
the capabilities of most implementations of the language.
Current practice:
This is believed to be very close to compatible with the Franz, Lucid,
Coral, and Texas Instruments implementations. It is probably
compatible or nearly compatible with other "Lisp Machine"
implementations.
Adoption cost:
Not known. Probably moderate or low -- for most implementations. The
cost would be to implementors rather than users since this part of the
language is currently underspecified. The author believes the cost
will be reasonable for KCL, an implementation where there is some
concern about this issue.
Benefits:
Users would be able to use aggregate objects in constants with
confidence about the behavior of their code.
Conversion cost:
Where this proposal *requires* different behavior than an existing
implementation, there is a conversion cost for users of that
implementation. It appears that this cost will be small, less than
the cost of leaving things unspecified.
Esthetics:
Since there is no adequate definition at present, a fuller definition
would be more esthetic.
Discussion:
This proposal does leave some user-visible attributes of objects
unspecified across the compile-and-load process, except that they must
be consistent with the attributes that must be retained. This
situation is a compromise between the desire for full specification on
the one hand, and on the other hand the desire to leave freedom for
different implementations to remain different and to support some
optimizations such as compacting hash tables and "simplifying" arrays.
Proposals will be entertained for tighter specification of datatypes
such as arrays.
The full extension of the concept of coalescing of constants is to say
that they can be coalesced exactly when they are similar as constants.
Comparing functions is hard. One could define an operation that
converts an interpreted function into a lambda expression. One could
say that interpreted functions are similar as constants when their
associated lambda expressions are similar in the appropriate sense.
This similarity of lambda expressions would be syntactic, but would
have to allow for possible inline macro expansion. Other
transformations would have to be prohibited, or the functions would
have to report themselves as compiled.
This proposal seems to deal with the question of how to test whether
constants in different Lisp address spaces are similar as constants.
That appears to be important.
We need someone expert with floating-point computation to review the
discussion of similarity of floating point numbers as constants.
The definition of similarity for random-states supports the
possibility of random states that are immutable because of being in
compiled constants.
Interest has been expressed by a number of people including users, in
support for user-definable "dumping" of CLOS objects and structure
instances. That seems to be recognized as powerful and important, but
we are looking for an appropriate person to make a proposal or
proposals.
This subsumes the isse CONSTANT-ARRAY-ATTRIBUTES.
∂21-Dec-88 0455 CL-Compiler-mailer RE: Re: issue COMPILER-DIAGNOSTICS, version 7
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 21 Dec 88 04:55:37 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa13840; 21 Dec 88 7:45 EST
Received: from draper.com by RELAY.CS.NET id ab13768; 21 Dec 88 7:32 EST
Date: Wed, 21 Dec 88 07:31 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: RE: Re: issue COMPILER-DIAGNOSTICS, version 7
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER
From: CCFVX3::SEB1525 "Steve Bacher (Batchman)" 21-DEC-1988 07:31
To: IN%"Gray@dsg.csc.ti.COM",SEB1525
Subj: RE: Re: issue COMPILER-DIAGNOSTICS, version 7
The problem with DRIBBLE is that its definition is tied to *STANDARD-OUTPUT*
rather than to *TERMINAL-IO*, which would make more sense. Since the other
streams are normally synonym streams of *TERMINAL-IO*, such default behavior
would automatically pick up *STANDARD-OUTPUT*, *ERROR-OUTPUT*, *DEBUG-IO*,
and whatever else - as well as NOT picking up *STANDARD-OUTPUT* when it was
redirected to a file - maybe not desirable or compatible behavior but seemingly
more "logical" to me. Anyhow, DRIBBLE doesn't seem to be under discussion by
cl-cleanup (unless I am mistaken), so enough about that.
This everything-handler stuff has potential. Why not redefine PRINT as
signalling the PRINT condition so users can code a handler to capture all
Lisp output? That could even replace DRIBBLE. The possibilities are endless.
:-)
Seriously, it is a very bad idea to start saying that such-and-such a set of
messages should go to *TRACE-OUTPUT* because it is sort of useful in the same
way as actual TRACE output. If we don't watch out, we'll be sending all kinds
of messages to all kinds of streams and the CL user won't know what's coming
or going. Let's nip this one in the bud.
∂21-Dec-88 0818 CL-Compiler-mailer Re: CONSTANT-COMPILABLE-TYPES:SPECIFY, V4
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 21 Dec 88 08:18:23 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA16137; Wed, 21 Dec 88 08:19:16 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA07154; Wed, 21 Dec 88 08:15:56 PST
Received: from Sun.COM (sun-arpa) by clam.sun.com (3.2/SMI-3.2)
id AA22650; Wed, 21 Dec 88 08:16:53 PST
Received: from cs.utah.edu by Sun.COM (4.1/SMI-4.0)
id AA16133; Wed, 21 Dec 88 08:18:51 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA18623; Wed, 21 Dec 88 09:15:25 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA08589; Wed, 21 Dec 88 09:15:20 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812211615.AA08589@defun.utah.edu>
Date: Wed, 21 Dec 88 09:15:18 MST
Subject: Re: CONSTANT-COMPILABLE-TYPES:SPECIFY, V4
To: cperdue@Sun.COM (Cris Perdue)
Cc: cl-compiler%clam@Sun.COM
In-Reply-To: cperdue@Sun.COM (Cris Perdue), Tue, 20 Dec 88 17:05:48 PST
On the whole, it looks reasonable. I think I would like to make a few
minor editorial tweaks here and there (clarifying that this proposal
applies to self-evaluating constants as well as quoted constants, adding
cross-references to the related issues, etc.) before sending this out to
the X3J13 mailing list.
I have only two minor complaints with the content of the proposal.
The first is that dumping a constant readtable is unlikely to be very
useful in an implementation that cannot dump compiled function
constants. The second is that I'm still not convinced that requiring
non-compiled, non-closed function constants to be dumpable buys
anything for the user, since an implementation is always free to make
all functions compiled. Rather than modify the proposal, at this point
I'd be happy with just adding a note to the discussion section.
-Sandra
-------
∂21-Dec-88 1224 CL-Compiler-mailer Summary of active issues, 12/21/88
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 21 Dec 88 12:24:48 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA25945; Wed, 21 Dec 88 13:23:50 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA00214; Wed, 21 Dec 88 13:23:47 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812212023.AA00214@defun.utah.edu>
Date: Wed, 21 Dec 88 13:23:46 MST
Subject: Summary of active issues, 12/21/88
To: cl-compiler@sail.stanford.edu
Here is the latest summary of pending cl-compiler issues.
These issues appear to be ready for release. There has been no
discussion on any of these issues since the latest versions were sent
out (weeks and weeks ago) and everybody on the cl-compiler list should
have had sufficient time and warning by now to comment on them. I
plan to distribute these writeups to the X3J13 mailing list by the
first of the year, and I think there is a reasonable chance that we
could vote on these at the January meeting.
ALLOW-LOCAL-INLINE
COMPILE-ENVIRONMENT-CONSISTENCY
COMPILER-LET-CONFUSION
DEFCONSTANT-SPECIAL
LOAD-TIME-EVAL
SHARP-COMMA-CONFUSION
The next bunch of issues are those that have actively been under
discussion within the past week or two. Because these issues haven't
yet stabilized and some of you may not have had time to comment on
them, I do not think it is reasonable to request a vote on them at the
upcoming meeting. However, I would like to distribute the writeups on
these issues to X3J13 in advance of the meeting, as drafts for
discussion. If you have comments on these issues that you want
incorporated before I send them out, please get them in by Jan 6th.
COMPILER-DIAGNOSTICS
Version 7 sent out on Dec 16.
COMPILER-VERBOSITY
Version 4 mailed Dec 21.
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Version 7 sent out on Dec 16.
Still need help with CLOS defining macros.
DEFINING-MACROS-NON-TOP-LEVEL
Version 5 mailed Dec 16.
EVAL-WHEN-NON-TOP-LEVEL
Version 2 mailed Dec 16.
QUOTE-MAY-COPY
Do we really need all three options in the latest writeup?
Need to clarify effects on other constant proposals.
CONSTANT-COMPILABLE-TYPES
Version 4 mailed Dec 20.
CONSTANT-CIRCULAR-COMPILATION
CONSTANT-COLLAPSING
May need minor tweaks (how affected by QUOTE-MAY-COPY)
CONSTANT-MODIFICATION
Ready for release?
The following issues are those which I don't plan to work on myself
until after the January meeting:
CONSTANT-ARRAY-ATTRIBUTES
Subsumed by CONSTANT-COMPILABLE-TYPES
COMPILE-FILE-ENVIRONMENT
Superseded by issue SYNTACTIC-ENVIRONMENT-ACCESS, unless that issue
has died.
DEFCONSTANT-NOT-WIRED
Still under discussion, no consensus yet
DEFCONSTANT-VALUE
Subsumed by issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
DEFINE-OPTIMIZER
Waiting for revisions (Pitman)
FILE-COMPILATION
same issue as CONSTANT-COMPILABLE-TYPES
PROCLAIM-ETC-IN-COMPILE-FILE
Waiting for resolution of related cleanup issues (DEFPACKAGE,
IN-PACKAGE-FUNCTIONALITY)
SYNTACTIC-ENVIRONMENT-ACCESS
Waiting for new writeup (Benson)
WITH-COMPILATION-UNIT
Waiting for revisions to existing proposal (Pitman)
-------
∂21-Dec-88 1223 CL-Compiler-mailer issue COMPILER-VERBOSITY, version 4
Received: from cs.utah.edu ([128.110.4.21]) by SAIL.Stanford.EDU with TCP; 21 Dec 88 12:23:48 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA25909; Wed, 21 Dec 88 13:22:43 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA00208; Wed, 21 Dec 88 13:22:40 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812212022.AA00208@defun.utah.edu>
Date: Wed, 21 Dec 88 13:22:39 MST
Subject: issue COMPILER-VERBOSITY, version 4
To: cl-compiler@sail.stanford.edu
Forum: Compiler
Issue: COMPILER-VERBOSITY
References: CLtL p. 438-329; 426
issue COMPILER-DIAGNOSTICS
Category: CHANGE/CLARIFICATION/ENHANCEMENT
Edit History: V1, 25 Oct 1988, Sandra Loosemore
V2, 12 Dec 1988, Dan L. Pierson (add USE-CONDITIONS)
V3, 15 Dec 1988, Dan L. Pierson (expand on conditions)
V4, 21 Dec 1988, Dan L. Pierson (reword and clarify)
Problem Description:
Implementations vary widely in the amount of information that is printed
out by COMPILE-FILE. In some situations, it would be useful to control
how much information is printed.
Proposal COMPILER-VERBOSITY:LIKE-LOAD:
Introduce a special variable, *COMPILE-VERBOSE*, with an implementation-
dependent initial value.
Add :VERBOSE and :PRINT keyword arguments to the function COMPILE-FILE,
analogous to those for the function LOAD.
The :VERBOSE argument (which defaults to the value of *COMPILE-VERBOSE*),
if true, permits COMPILE-FILE to print a message in the form of a comment
to *STANDARD-OUTPUT* indicating what file is being compiled and other
useful information.
The :PRINT argument (which defaults to NIL), if true, causes
information about top-level forms in the file being compiled to be
printed to *STANDARD-OUTPUT*. Exactly what is printed will vary from
implementation to implementation, but nevertheless some information
will be printed.
Rationale:
This proposal makes COMPILE-FILE behave like LOAD. There is already
some precedent for doing this (for example, issue COMPILE-FILE-PACKAGE,
which makes COMPILE-FILE as well as LOAD rebind *PACKAGE*).
Current Practice:
Lucid provides a :MESSAGES keyword argument to COMPILE-FILE, which can
either be a stream to send progress messages to, or NIL to suppress messages.
The default value is T, which sends messages to "the standard terminal
device".
On the TI Explorer, COMPILE-FILE displays the name of the function being
compiled when the option :VERBOSE T is given or special variable
COMPILER:COMPILER-VERBOSE is true. (In other words, they use :VERBOSE
to mean what this proposal says to use :PRINT for.)
Cost to implementors:
This is an incompatible change for some implementations. While the
changes required should be conceptually simple, their implementation
may involve a significant amount of grunt work. At least two
implementations already provide some similar mechanism for suppressing
messages.
Cost to users:
Some (non-portable) user code may break in implementations where this is
an incompatible change.
Specifying that the :PRINT argument defaults to NIL is consistent with
LOAD, but in most implementations the default now is to print out a
lot of information about each function or top-level form. Some users
may find it irritating to have to type in :print t to get the same
amount of information they're used to seeing.
Benefits:
Users are given a portable way to control how much information is printed
by COMPILE-FILE.
Proposal COMPILER-VERBOSITY:USE-CONDITIONS:
Add the new subtype of CONDITION, NOTICE, defined in
COMPILER-DIAGNOSTICS (V5). Add a new subtype of NOTICE, INFO.
Require compilers to "print" all messages covered by this proposal by
using the function NOTICE to signal a condition of type INFO instead
of directly writing the message. For the purposes of this proposal
"compilers" refers to both COMPILE and COMPILE-FILE.
Note that, since a compiler is never required to print any messages
covered by this proposal, no portable program may assume that any
conditions of type INFO will actually be signalled.
Rationale:
This allows informational compiler messages and compiler diagnostics
to be handled in a uniform manner with a simple, well defined way for
the user to gain any desired degree of control over these messages.
Current Practice:
No one currently controls compiler messages via the condition system.
Cost to implementors:
This is an incompatible change for all implementations. It should be
a conceptually simple change to make once an implementation supports
the condition system, however the actual implementation of the change
may involve a significant amount of grunt work.
All existing implementations can continue support their current
message control interfaces as long as the implementation of their
current interface is changed to comply with this proposal. This could
be done by:
1. Causing the old interface to either establish a condition
handler that accepts messages that shouldn't be printed and
does nothing with them. Note that it would not be legal to
make the handler print the messages that should be printed,
because a user handler must still be given a chance to look at
them.
2. Changing the old interface to conditionally write the message
as it used to, except that NOTICE is used to actually write the
message.
Cost to users:
Some user code may break in implementations which remove any
(non-portable) existing mechanisms to control compiler output.
Benefits:
Users are given a portable way to control how much information is printed
by COMPILE-FILE.
Aesthetics:
Using a well defined, already existing, general mechanism is more
aesthetically pleasing than adding another ad-hoc flag or special
variable.
Discussion:
Rather than just treating :PRINT and :VERBOSE as boolean values, it
might be useful to have them convey more information. For example,
Pitman has suggested using keyword values like :BRIEF or :DETAILED to
allow varying amounts of information of each type to be printed.
Alternatively, it might be reasonable to follow Lucid's precedent to
allow the values of :PRINT and :VERBOSE to be streams to allow
messages to be directed somewhere other than *STANDARD-OUTPUT*.
Either of these suggestions could reasonably be made to apply to LOAD
as well, but the intent of LIKE-LOAD is to make COMPILE-FILE
behave like LOAD, not to change the specification of LOAD.
Loosemore believes that using conditions for this purpose is not
appropriate, because this issue deals with messages indicating the
normal progress of the compiler and conditions are supposed to be used
to signal exceptional (non-ordinary) situations.
Pierson believes that conditions provide a well defined, portable,
non-intrusive interface for user control of infrequent events. While
the use of conditions is not notably efficient, compiler informational
messages are sufficiently infrequent that this should not impose a
noticeable performance penalty.
Pierson would like to see LOAD, etc. changed to also use this
interface.
The two proposals are not mutually incompatible in that the LIKE-LOAD
keywords can be added to an implementation whether or not it is based
on USE-CONDITIONS.
-------
∂22-Dec-88 1110 CL-Compiler-mailer RE: Re: issue COMPILER-DIAGNOSTICS, version 7
Received: from ti.com by SAIL.Stanford.EDU with TCP; 22 Dec 88 11:09:51 PST
Received: by ti.com id AA05219; Wed, 21 Dec 88 12:22:54 CST
Received: from Kelvin by tilde id AA26928; Wed, 21 Dec 88 12:04:30 CST
Message-Id: <2807719437-5871689@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 21 Dec 88 12:03:57 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Cc: cl-compiler@SAIL.STANFORD.EDU
Subject: RE: Re: issue COMPILER-DIAGNOSTICS, version 7
In-Reply-To: Msg of Wed, 21 Dec 88 07:31 EST from "Steve Bacher (Batchman)" <SEB1525@draper.com>
> The problem with DRIBBLE is that its definition is tied to *STANDARD-OUTPUT*
> rather than to *TERMINAL-IO*, which would make more sense.
Zetalisp had both a DRIBBLE-START function which bound STANDARD-OUTPUT
and a DRIBBLE-ALL function which bound TERMINAL-IO. We still support
DRIBBLE-ALL as an extension to Common Lisp. Sometimes you really want
to record everything and sometimes you don't want interactive debugging
to be included, so both options are really needed.
I can understand wanting to be able to separate error messages from the
normal output of a program, but in the case of the compiler, the error
and status messages are the only text output it produces, so there is
nothing to separate them from.
> Seriously, it is a very bad idea to start saying that such-and-such a set of
> messages should go to *TRACE-OUTPUT* because it is sort of useful in the same
> way as actual TRACE output. If we don't watch out, we'll be sending all kinds
> of messages to all kinds of streams and the CL user won't know what's coming
> or going. Let's nip this one in the bud.
There is a broader question here though, that I have run into when
writing various utility programs. When I want to display messages
telling what's happening now during a long process, it is not clear from
CLtL where they should be written. Certainly writing to *TERMINAL-IO*
works, but there is an implication that that isn't quite proper since
there would be no way to redirect it. Where then? *ERROR-OUTPUT*,
*QUERY-IO*, *DEBUG-IO*, might all seem plausible, but these are status
messages, which are not errors, not queries, and don't have anything to
do with debugging. So that leaves *TRACE-OUTPUT*, which seems most
likely since TRACE messages seems to be the only example of
what's-happening-now messages specified by CLtL. So I think it would
actually make things _less_ confusing for users if we were to clarify that
*TRACE-OUTPUT* is the place for status messages.
∂22-Dec-88 1137 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 22 Dec 88 11:37:27 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04437g; Wed, 21 Dec 88 23:17:34 PST
Received: by bhopal id AA10287g; Wed, 21 Dec 88 23:18:10 PST
Date: Wed, 21 Dec 88 23:18:10 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812220718.AA10287@bhopal>
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Cc: @cs.utah.edu:sandra@defun, cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton's message of Sun, 18 Dec 88 01:08:17 GMT <9851.8812180108@subnode.aiai.ed.ac.uk>
Subject: issue QUOTE-MAY-COPY, version 2
re: > ... To me it seems pretty clear that any copying
> of constants that goes on happens as a result of transforming an
> arbitrary data structure into a program.
Why are the constants transformed at all? I can see why the
program text (i.e., the list) might be transformed. The compiler
might compile it, the interpreter might macroexpand it or partially
compile it. But, unless some writing to a file is involved, why
would any processing be done to the constants?
The basic flaw we have been having in this discussion is that whenever
someone proposes "Let QUOTE have semantics **as if** it made a copy",
then someone else reads that to be saying "QUOTE must necessaryily
copy its argument". The quote (no pun intended) you have from Sandra's
msg is really in the form of a conditional "IF quote makes a copy, then
it can only happen under such-and-such a set of circumstances."
The issue that QUOTE-MAY-COPY is proposing is merely to **defeat** the
counter proposals QUOTE-MUST-NOT-COPY; or QUOTE-MUST-PRESERVE-EQLness.
It is not to say that any implementation ever has to do any copying.
I read Cris's comments as saying that QUOTE-MAY-COPY is the only
consistent interpretation, because even if an implementation of QUOTE
itself never does any copying, the semantics of the result will be
forced to be "maybe is a copy" by other constraints (such as
consistency with file compilation). I think you yourself even
acknowledge this point later in your msg.
-- JonL --
∂22-Dec-88 1140 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 5
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 22 Dec 88 11:40:00 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04410g; Wed, 21 Dec 88 20:40:22 PST
Received: by bhopal id AA09960g; Wed, 21 Dec 88 20:40:59 PST
Date: Wed, 21 Dec 88 20:40:59 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812220440.AA09960@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Fri, 16 Dec 88 17:18:34 MST <8812170018.AA05990@defun.utah.edu>
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 5
re: Clarify that all defining macros which create functional objects
(including DEFMACRO, ...) must ensure that those functions are
defined in the lexical environment in which the defining macro is
executed.
Wouldn't this read more smoothly if it said "in which the defining
form is evaluated"?
re: (3) Clarify that ``top-level forms'' are evaluable data objects read
in from an input source (such as a keyboard or disk file) by ...
I'm not at all comfortable tying in the definition of "toplevel" to READ.
In particular, lots of so-called top-level forms are not explicitly read
in, but rather are constructed up by macros which return something like
`(PROGN (DEFUN ...) (DEFMACRO ...) ...<whatever>...)
I liked Walter's suggestion that "toplevel" be made synonymous with
"null lexical environment". Of course, the difficulty there is that
one must specify that the call to (BAR) in each example below is
not in a null environment:
(FOO (BAR)) ;where FOO is an ordinary function
(<special-form> ... (BAR) ...)
where <special-form> is any listed on CLtL page 57 except PROGN, QUOTE,
THE, and EVAL-WHEN. For the exceptions, (BAR) is "at toplevel" iff
the wrapping form is "at toplevel".
re: Specify that top-level forms in a file being
compiled are guaranteed to be processed sequentially, but the order in
which subforms of a top-level form are processed by the compiler is
explicitly left unspecified.
I don't understand the motivation for saying anything at all about the
order of processing the subforms; in particular, it conflicts with a
perceived requirement that if (PROGN (A) (B)) is at toplevel, then (A)
and (B) must be processed " at toplevel" and **in order**.
-- JonL --
∂22-Dec-88 1141 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 22 Dec 88 11:41:28 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04404g; Wed, 21 Dec 88 20:21:20 PST
Received: by bhopal id AA09932g; Wed, 21 Dec 88 20:21:57 PST
Date: Wed, 21 Dec 88 20:21:57 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812220421.AA09932@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Fri, 16 Dec 88 17:16:28 MST <8812170016.AA05978@defun.utah.edu>
Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 2
Since we are tending towards flushing COMPILER-LET, then I favor
restricting the COMPILE situation to "toplevel" forms. However, that
entails straightening out the mess about what really is "toplevel". We
cannot "pass" this proposal without a satisfactory resolution of the
toplevel definition -- e.g., PROGN "passes ``top-level'' through", but
LET does not (even if the list of bound variables is null).
I'm not sure if this has been answered in subsequent mailings, but
the analysis given under the heading:
"When an EVAL-WHEN form is processed by the compiler:"
lists two alternatives in a way that might imply they are mutually
exclusive:
(1) If the situation COMPILE is specified:
...
(2) If the situation LOAD is specified, ...
One needs to cover the case when both COMPILE and LOAD are specified.
In addition, does the compiler act differently on situation (EVAL)
than it does on situation (LOAD)? How about (EVAL LOAD)?
-- JonL --
∂22-Dec-88 1433 CL-Compiler-mailer Re: CONSTANT-COMPILABLE-TYPES:SPECIFY, V4
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 22 Dec 88 14:33:39 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA08749; Thu, 22 Dec 88 14:35:53 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA28335; Thu, 22 Dec 88 14:32:34 PST
Received: from Sun.COM (sun-arpa) by clam.sun.com (3.2/SMI-3.2)
id AA00250; Thu, 22 Dec 88 14:33:31 PST
Received: from NSS.Cs.Ucl.AC.UK by Sun.COM (4.1/SMI-4.0)
id AA02385; Thu, 22 Dec 88 10:27:28 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa05775; 22 Dec 88 18:10 GMT
Date: Thu, 22 Dec 88 18:07:53 GMT
Message-Id: <20333.8812221807@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: CONSTANT-COMPILABLE-TYPES:SPECIFY, V4
To: sandra <@cs.utah.edu:sandra@defun>, Cris Perdue <cperdue@Sun.COM>
In-Reply-To: Sandra J Loosemore's message of Wed, 21 Dec 88 09:15:18 MST
Cc: cl-compiler <>
> I have only two minor complaints with the content of the proposal.
> The first is that dumping a constant readtable is unlikely to be very
> useful in an implementation that cannot dump compiled function
> constants. The second is that I'm still not convinced that requiring
> non-compiled, non-closed function constants to be dumpable buys
> anything for the user, since an implementation is always free to make
> all functions compiled. Rather than modify the proposal, at this point
> I'd be happy with just adding a note to the discussion section.
Although I didn't say anything about it before, I was always bothered
by the idea that functions would be dumped in readtables. Since it's
pretty clear that not all implementations can dump all functions, users
can't rely on it at all; and then the whole idea of dumping a readtable
begins to seem suspect.
Can readtable functions be symbols?
BTW, isn't function equivalence already covered by CLtL?
Cheers,
Jeff
∂22-Dec-88 1601 CL-Compiler-mailer Issue ALLOW-LOCAL-INLINE (V3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Dec 88 16:01:46 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 511678; Thu 22-Dec-88 18:53:24 EST
Date: Thu, 22 Dec 88 18:53 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue ALLOW-LOCAL-INLINE (V3)
To: Gray@DSG.csc.ti.com
cc: CL-Compiler@SAIL.Stanford.edu
In-Reply-To: <2804115121-1674908@Kelvin>
Message-ID: <881222185310.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
For the record, I generally like the spirit of the current proposal.
I have a couple of specific comments on the wording that I hope can be
addressed before it comes to an actual vote because I think they will
make the proposal clearer and easier for others to evaluate, but they
don't affect my actual vote:
* The opening of the proposal is awkwardly worded. Just about any wording
would be better. As a straw man...
``Clarify that to define a function FOO which is not INLINE by default
but for which (DECLARE (INLINE FOO)) will make FOO be locally inlined,
the proper definition sequence is:''
* The test cases don't illustrate the problem you're trying to solve.
Change "(defun f4 ...)" to:
(defun f4 (b) (f3 b)) ;F3 is not inline.
(defun f5 (c) (declare (inline f3)) (f3 c)) ;F3 is locally inline.
(defun f6 (c) (f3 c)) ;The local effect is not persistent.
The surrounding descriptive text must be changed to be consistent, of course.
-----
As an aside, I would also like to see the following issue addressed.
Perhaps it's enough different that it should be done via a separate
issue, but I'll just mention it here and let you sort out what to do:
You describe the effect of PROCLAIM INLINE as two-fold -- (a) set up for
the definition of function to record extra info and (b) enable inlining.
I think it would be nice if (a) were "used up" by the next definition,
so that
(PROCLAIM '(INLINE F))
(DEFUN F (X) X)
(DEFUN F (X) (+ X 1))
would leave you with a NOTINLINE definition of F. You'd have to do
(PROCLAIM '(INLINE F))
(DEFUN F (X) X)
(PROCLAIM '(INLINE F))
(DEFUN F (X) (+ X 1))
to get F to keep being inline. Note that (b) would not be used up, so you could do
(PROCLAIM '(INLINE F))
(DEFUN F (X) X)
(PROCLAIM '(NOTINLINE F))
(PROCLAIM '(INLINE F))
(PROCLAIM '(NOTINLINE F))
(PROCLAIM '(INLINE F))
(PROCLAIM '(NOTINLINE F))
...
all you wanted without losing the inline info for F. The main feature would be
that you could write:
(DEFMACRO DEFUN-INLINE (FN BVL &BODY FORMS)
`(PROGN (PROCLAIM '(INLINE ,FN))
(DEFUN ,FN ,BVL ,@FORMS)))
and then do
(DEFUN-INLINE F (X) X)
and have doing
(DEFUN F (X) X)
later on not wind up with F being accidentally inline.
∂22-Dec-88 1650 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, V3
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Dec 88 16:49:58 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 511694; Thu 22-Dec-88 19:48:22 EST
Date: Thu, 22 Dec 88 19:47 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-LET-CONFUSION, V3
To: sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8810311654.AA02513@defun.utah.edu>,
<8812212023.AA00214@defun.utah.edu>
Message-ID: <881222194753.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
In spite of the fact that there is no recent mail on this issue, I'm
bugged that you think this is stable.
I have voiced very strong objection to this proposal and there is no
mention of the fact that I dissent, nor my reasons in the discussion.
[As an aside, I feel compelled to note that I feel that a key distinction
between the proposals circulated on CL-Cleanup and those circulated
on CL-Compiler is that the CL-Cleanup forum is extremely concerned with
getting a fair presentation of everyone's position. In general, Cleanup
does not drop alternative proposals unless they can achieve consensus
that it is not worth pursuing the alternate proposals. Since this
proposal doesn't satisfy me and others which were closer to correct
have been dropped, I do not believe that the presentation is unbiased,
and I believe a disservice is done to the community. Remember that
the full community is not necessarily fairly represented within the
microcosm of CL-Compiler, so just because something is not "receiving
much support" within CL-Compiler doesn't mean it won't outside. The
question is what is technically defensible. The REQUIRE-PREPASS proposal
was, for example, technically defensible and arguably the right thing.
Moreover, since you are proposing an incompatible change, my feeling is
that the burden is on you to demonstrate that you have a compelling
justification for doing so. I don't think you've made that case fairly,
presenting arguments both pro and con. I don't think this presentational
bias is unique to this issue.]
Returning from the meta-level, let me say that I continue to believe
strongly that this whole issue is ill-presented. I agree that COMPILER-LET
is ill-presented in CLtL, but that doesn't mean it's useless.
This proposal reads like "Well, they didn't describe it right and we
can't figure out how to make sense of it, so let's pretend it served no
purpose and remove it."
I've made a case that it expresses a useful high level concept and that
it can be coherently implemented. The truth is not that it is impossible
to either describe coherently or to implement, only that there is a cost
to some implementations to bring them in line with such a description.
For the presentation to be fair, it must present the following things:
- The original intent of COMPILER-LET, which acknowledges that it
had a valid, useful, and potentially portable purpose.
- A description of why COMPILER-LET was ill-described in CLtL,
hiding the original intent.
- A description of how the poor description in CLtL led
implementations to make certain assumptions about how they could
implement some kinds of things (like environments).
- A description of why these assumptions that have been made by
existing implementations now mean that implementing the correct
semantics would have a certain non-negligible cost to certain
implementations, and a serious account of what that cost might be.
- A description of the two legitimate options:
* Fix the description of COMPILER-LET.
* Remove COMPILER-LET.
I want people to make an informed decision. If on the basis of a fairly
presented case, people make a reasoned decision to not go with COMPILER-LET,
I will not be unhappy.
If, instead, you present a proposal which shows only a highly biased
viewpoint with no attempt made to be fair, and people vote on this based
on what I expect will be a misunderstanding of the true situation,
then I will be quite unhappy.
These cleanup writeups will stand as the closest things to rationales
for why we changed the language or did not. I want the record to reflect
the full set of facts, and our ability to make reasoned choices about
hard issues. I do not want the record to reflect someone railroading
something through without proper presentation.
I hope this message suffices to dispell any belief that we are all
basically ready for a vote on this issue as currently presented.
∂23-Dec-88 0643 CL-Compiler-mailer RE: Issue ALLOW-LOCAL-INLINE (V3)
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 23 Dec 88 06:43:00 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa12543; 23 Dec 88 9:40 EST
Received: from draper.com by RELAY.CS.NET id ab00930; 23 Dec 88 9:35 EST
Date: Fri, 23 Dec 88 08:50 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: RE: Issue ALLOW-LOCAL-INLINE (V3)
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER
From: CCFVX3::SEB1525 "Steve Bacher (Batchman)" 23-DEC-1988 08:43
To: IN%"KMP@SCRC-STONY-BROOK.ARPA",SEB1525
Subj: RE: Issue ALLOW-LOCAL-INLINE (V3)
re: (DEFUN F (X) X)
(DEFUN F (X) (+ X 1))
Come on - do you really mean for people to redefine functions in the same file?
I thought that's what FLET was created to avoid. Shouldn't it "be an error"
to define the same function more than once in a file being compiled? Or is
that another potential issue?
In any case, I don't see why any effort should go into modifying the behavior
of a CL construct to support such questionable practice.
∂23-Dec-88 0910 CL-Compiler-mailer RE: Issue ALLOW-LOCAL-INLINE (V3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Dec 88 09:10:11 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 511914; Fri 23-Dec-88 12:08:58 EST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 511897; Fri 23-Dec-88 11:46:47 EST
Date: Fri, 23 Dec 88 11:46 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: RE: Issue ALLOW-LOCAL-INLINE (V3)
To: SEB1525%draper.com@RELAY.CS.NET
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <881223114630.1.KMP@BOBOLINK.SCRC.Symbolics.COM>
Resent-To: CL-Compiler@SAIL.Stanford.EDU
Resent-From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Resent-Date: Fri, 23 Dec 88 12:08 EST
Resent-Message-ID: <881223120843.3.KMP@BOBOLINK.SCRC.Symbolics.COM>
In the same file only in a very strange sense: I'm worried about interactive
debugging, where I make something inline and then later decide that was a bad
idea. Symbolics Common Lisp has a construct called DEFSUBST which behaves
identically to the DEFUN-INLINE I described. The problem is that CL's INLINE
semantics screws it because if you change a DEFSUBST to a DEFUN in the editor
and re-evaluate that single definition (which is how you do program development
on LispM family computers), you find that even though you've now written DEFUN,
the INLINE info set up by the DEFSUBST persists because there is no way for the
editor to know that you hadn't written
(PROCLAIM '(INLINE FOO))
(DEFUN FOO ...)
and that you weren't just re-evaluating the DEFUN part expecting the INLINE
stuff to persist. If indeed we made the contract of INLINE be that the info
went away on subsequent redefinition, then the editor could know you weren't
just reevaluating the DEFUN hoping the INLINE info would persist by definition:
the INLINE information wouldn't be permitted to persist, and you'd have to
re-evaluate both the (PROCLAIM '(INLINE ...)) and the DEFUN to get the info to
persist.
-Unfortunately-, as I've just realized in writing this, if you do
(PROCLAIM '(INLINE FOO))
(DEFUN FOO ...)
(PROCLAIM '(NOTINLINE FOO))
(PROCLAIM '(INLINE FOO))
(PROCLAIM '(NOTINLINE FOO))
(PROCLAIM '(INLINE FOO))
and later do a DEFUN, there is still no way for the editor to tell the
difference between the two kinds of INLINE declaration, and so the later
DEFUN would still end up inlined.
This makes me think that Gray was right in suggesting that ALLOW-INLINE
is needed. I'll have to think on this more before sending mail to the whole
list.
∂23-Dec-88 0908 CL-Compiler-mailer Issue: QUOTE-MAY-COPY (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Dec 88 09:08:45 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 511911; Fri 23-Dec-88 12:07:32 EST
Date: Fri, 23 Dec 88 12:07 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: QUOTE-MAY-COPY (Version 2)
To: CL-Compiler@SAIL.Stanford.EDU
Message-ID: <881223120713.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
I asked Moon about his feelings on this. He thinks pretty strongly that
the ALWAYS option is the only practical one to pursue. Partly, he says,
because it's maximally compatible with current practice and partly
because it avoids making COMPILE-FILE seem different.
I personally don't put a lot of stock in the issue of COMPILE-FILE being
different. There are many `axes of consistency' that you can look at here,
and depending on how you look at it, you weigh things differently.
I do, however, concur with his assessment that it's compatible with
current practice, and I guess I have to admit that in the end that may
have to be the overriding consideration.
However, my support for ALWAYS is somewhat conditional. The subsequent
paragraphs embody my view to date on this issue:
In principle, I favor option ALWAYS, permitting copying of quoted
structure to a constants area in any of EVAL, COMPILE, or COMPILE-FILE
situations, as appropriate to the implementation.
It should not be concluded from this that I favor restrictions on the
kinds of data which may be quoted, however. The wording of option ALWAYS
should be ammended to say that such copying is permitted only when the
system can reliably deduce whether such copying is `appropriate,'
and avoid it in cases where it is not. The purpose of such wording would
be to avoid placing restrictions on what kinds of structures a user can
or cannot quote.
So, for example, if an implementor cannot in some context figure out how
to detect circularities in quoted structure in order to either decline
copying or correctly copy the circular form, then the implementation is
not permitted to attempt copying in such contexts.
Note however that because of special considerations forced by the external
representation of data in compiled files, I go along with (and encourage)
the establishment of a known subset of types which can be quoted (or used
as self-evaluating constants) in code to be reliably processed by the file
compiler. Coincidentally, such restrictions might make it easier for an
implementation to know whether copying was going to succeed in the case of
loading compiled code from a file, but technically these restrictions are
not motivated by any consideration of what kinds of structures might or
might not be possible to QUOTE.
My inclination is also to believe that copying should not be done
repeatedly, and we should find a way to express this. That is, repeated
execution of code in the same execution environment should return an EQL
result (or some such). This is important to guaranteeing efficiency. Even
in copying implementations, it is not necessary that such constants be
allocated in a read-only area or some such to achieve this effect. For
example, quoted structure could be placed in a special array and QUOTE
could be implemented using AREF. What is important is that any of these
permissions we give for copying not be taken for a license that QUOTE
should be implemented by COPY-TREE or some other operation which cannot
be done in constant time.
∂23-Dec-88 1153 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 23 Dec 88 11:49:27 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa02063; 23 Dec 88 19:38 GMT
Date: Fri, 23 Dec 88 19:36:04 GMT
Message-Id: <21484.8812231936@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Jon L White <@sail.stanford.edu:jonl@lucid.com>
In-Reply-To: Jon L White's message of Wed, 21 Dec 88 23:18:10 PST
Cc: sandra <@cs.utah.edu:sandra@defun>, cl-compiler@sail.stanford.edu
> The basic flaw we have been having in this discussion is that whenever
> someone proposes "Let QUOTE have semantics **as if** it made a copy",
> then someone else reads that to be saying "QUOTE must necessarily
> copy its argument". The quote (no pun intended) you have from Sandra's
> msg is really in the form of a conditional "IF quote makes a copy, then
> it can only happen under such-and-such a set of circumstances."
Um, I guess it must be that some kind of misunderstanding is taking
place, but it looks like it may be on both sides. Perhaps I am somewhat
misreading Sandra and Chris, or misstating my own points, but I did
understand "may copy" to mean "may copy" and not "must copy". The
problem is that I'm not convinced QUOTE should be allowed to copy.
> The issue that QUOTE-MAY-COPY is proposing is merely to **defeat** the
> counter proposals QUOTE-MUST-NOT-COPY; or QUOTE-MUST-PRESERVE-EQLness.
> It is not to say that any implementation ever has to do any copying.
Just to make this clear, I currently favor the counter-proposals: I
would like to have EQL-identity preserved except when file operations
are involved.
For me, the first question is whether the semantics of file compilation
must, for consistency, carry over into the rest of the language. If
that's so, then you are right, and QUOTE must be allowed to copy. But
that's not all that must happen. The file compiler's restrictions on
what types can appear in constants and on whether constants can be
circular (if we decide there are circularity restrictions) must also
constrain the semantics of EVAl and COMPILE. Kent Pitman gave some
arguments in favor of distinguishing between COMPILE (and EVAL) and
COMPILE-FILE on the issues of types and circularity, and I think they
are good arguments, not to be cast aside without some careful thought.
> I read Cris's comments as saying that QUOTE-MAY-COPY is the only
> consistent interpretation, because even if an implementation of QUOTE
> itself never does any copying, the semantics of the result will be
> forced to be "maybe is a copy" by other constraints (such as
> consistency with file compilation). I think you yourself even
> acknowledge this point later in your msg.
What I have been trying to say was that (1) it may turn out that "QUOTE
may copy" is the only consistent interpretation, but (2) Chris's model
suggests that there might be a different consistent (or at least
reasonable) interpretation, namely that all copying (and coalescing
for that matter) is associated with file operations. Moreover, (3)
I think some of the arguments for consistency with file compilation
are at least not immediately convincing. We know, for example, that
a Common Lisp might always compile and so not have an interpreter-like
EVAL; but is it OK for a Common Lisp to have only a file compiler?
Some arguments seem to depend on that being OK.
-- Jeff
∂23-Dec-88 1236 CL-Compiler-mailer issue DEFCONSTANT-SPECIAL, version 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Dec 88 12:35:57 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 511989; Fri 23-Dec-88 14:42:19 EST
Date: Fri, 23 Dec 88 14:42 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue DEFCONSTANT-SPECIAL, version 2
To: sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8811221728.AA08181@defun.utah.edu>
Message-ID: <881223144205.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
I find p56 to be unambiguous:
``Certain global variables are reserved as ``named constants.''
They have a global value and may not be bound or assigned to.
At the very least, this quote must be in the problem description
in order for the description to be fair.
If there are competing passages, they should be cited as well.
Although I personally find it unambiguous, and I do not personally think
that a clarification is warranted, I generally accept that if someone
disagrees about the unambiguous nature of a passage, then that is an
existence proof that a clarification is in order, so I won't try to stop
the issue.
Nevertheless, I agree with GSB that for you to present this as a
clarification is at best misleading.
Further, you don't cite a single example motivating why it makes any
difference to you whether this is is a special or a lexical. To give
your case more weight, you would be best to show a case where it would
be useful to (for example) bind such a variable.
If PROCLAIM-LEXICAL passes, there will be these options:
- Constant names are pervasively global (G).
- Constant names are pervasively special (DG).
- Constant names are pervasively lexical (LG).
- Constant names cannot be bound, so may be any of global, special,
or lexical since it's not possible to tell the difference.
If they were pervasively global, then it would make no sense to bind
them, so we can discount that.
If they were pervasively special, then special binding them would affect
their global value and would mean you couldn't inline them, so we can
discount that.
If they are going to be bindable, it's clear that they have to be lexical.
If they are not going to be bindable, then it doesn't matter if they're
lexical or not.
I think you need to present two options:
- Clarify that names of constants cannot be bound.
I believe this is a simple clarification.
- Define that names of constants are permissible for use as local
variables.
I believe that a serious problem with making them available for use as
local variables is that macros will no longer be able to reliably use
them because they have to worry that a user has re-bound them to something
else.
I believe that people who want to use MOST-POSITIVE-FIXNUM and friends
as lexical (or special) variables which they can bind for their own uses
should shadow that symbol, leaving LISP:MOST-POSITIVE-FIXNUM to do its
job and not be bound.
If you want to present a case to the contrary, I think that's fine.
I just hope you fairly represent the viewpoints of us all so that X3J13
as a whole can make an informed decision.
∂23-Dec-88 1237 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 7
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Dec 88 12:36:07 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 511996; 23 Dec 88 15:15:55 EST
Date: Fri, 23 Dec 88 15:15 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue LOAD-TIME-EVAL, version 7
To: sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8810171902.AA22253@defun.utah.edu>
Message-ID: <881223151540.7.KMP@BOBOLINK.SCRC.Symbolics.COM>
I'm not yet ready to offer this version my stamp of approval, but I do
have a list of comments which if addressed would probably lead me to be
happy with it...
* I'm not sure I agree that semantic processing (macro expansion) of
LOAD-TIME-VALUE's argument should be deferred to run time.
Doing so forces macro libraries to be available which might otherwise
not have to be available.
It also means that loading will be incrementally slower, and may
do intermediate consing due to macroexpansion that could be avoided.
Anyway, if we make semantic processing occur in the compiler
environment, someone who really wants to can still defer it to runtime
by simply replacing things like
(LOAD-TIME-VALUE (MY-MACRO))
with
(LOAD-TIME-VALUE (EVAL '(MY-MACRO)))
As such, I think we should change this to say that full macroexpansion
is done at compile time.
* The sentence
It is not permissible to "collapse" either multiple
references to the same (EQ) LOAD-TIME-VALUE expression, or EQUAL
expressions.
is too confusing. Are the EQ expressions referred to source expressions,
and the EQUAL expressions results? Break this out into its own paragraph,
expand to clarify, and offer examples.
* Although I'm willing to take multiple evaluation in the interpreter
as a compromise position, I would like it mentioned in the discussion
that this was only an expedient to getting this issue accepted at all,
and that I'm not really happy about it. I have said that I think a
number of our lingering problems (with EVAL-WHEN, COMPILER-LET, and
this -- for example) are due to the presence of interpreters which do
not do a semantic-prepass at a known time. If I had my way, we would
require a semantic pre-pass and we would then be able to forbid
multiple evaluations even in the interpreter.
* Please change "is an important feature to include" in the first
paragraph of the discussion to "is an essential feature to include".
Believe it or not, I don't think just "important" is strong enough
here. Thanks.
* In cost to implementors, it says
In compiled code, (LOAD-TIME-VALUE <form>) is equivalent to '#,<form>...
but it should probably only say "most equivalent" or "very similar",
and then go on to highlight the issue of non-read-only-ness which #,
does not currently acknowledge.
∂23-Dec-88 1245 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Dec 88 12:44:59 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 512004; Fri 23-Dec-88 15:43:20 EST
Date: Fri, 23 Dec 88 15:43 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue SHARP-COMMA-CONFUSION, version 1
To: sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8810171903.AA22260@defun.utah.edu>
Message-ID: <881223154306.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
I approve of the ideas being discussed, but ONLY contingent on
LOAD-TIME-VALUE being introduced.
I don't think the current practice assesses things correctly.
Better than
#, is not used very frequently.
would be
Although #, is used infrequently in typical user code, the functionality
it provides is very important to some advanced applications. Maintainers
of such applications have generally expressed a willingness to give up #,
only if a suitable alternative is offered (see issue LOAD-TIME-EVAL).
CLOS and language translators are examples of pieces of code which have
been cited by people who say they could not be implemented efficiently in
Lisp without a facility such as this.
In Cost To Users, the DEFPARAMETER technique described has been demonstrated
to be unacceptable for the general problem. The importance of LOAD-TIME-EVAL
needs to be promoted here as well.
I am optimistic that LOAD-TIME-EVAL will pass, and so I don't think this
will keep #, from passing, but:
- I want people who vote for this to realize the importance of voting
for LOAD-TIME-EVAL.
- On the off chance LOAD-TIME-EVAL doesn't pass, I want people to have
been warned that the consequences were severe for some major applications.
- I want the records to reflect the actual rationale people should and
hopefully will be using to make these decisions.
In particular, the issue of LOAD-TIME-EVAL goes beyond "thinking of a
variable name". A bunch of other issues which were raised in mail are
left out here:
- There is no way for an expression from inside a program for a macro
to `emit' a top-level definition.
- Variables are high overhead (typically at least five pointer-size
units per symbol), and so zillions of independent names would bloat
space.
- Variables are typically slower than immediate quantities can be.
∂23-Dec-88 1452 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 7
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Dec 88 14:52:41 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 512061; Fri 23-Dec-88 17:51:07 EST
Date: Fri, 23 Dec 88 17:50 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-DIAGNOSTICS, version 7
To: sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8812162057.AA05870@defun.utah.edu>
Message-ID: <881223175045.0.KMP@BOBOLINK.SCRC.Symbolics.COM>
I think this proposal is unduly complicated.
The problem you state could be addressed by the following much simpler
proposal:
Specify that COMPILE and COMPILE-FILE return a second value, SUCCESS-P.
Define that compilers are permitted to handle conditions of type ERROR,
turning them into warnings and continuing to compile as appropriate,
but that if an error was turned into a warning so that COMPILE or
COMPILE-FILE could complete its operation, NIL must be returned as the
second value. The normal successful return value would be T.
As I see it, this doesn't preclude doing on a per implementation basis
the things you suggest in the proposal now on the table, but it is
conceptually simpler, does not constrain implementations nearly as
much, and is far less likely to be accused of being "gratuitous hair".
If you wanted to suggest a third return value, WARNINGS-P, I wouldn't
balk. I personally don't think it's needed. If I needed it, I would
probably just direct warnings to a string stream and then see if the
stream was non-null at the end. But I suppose if someone claims that the
circumstance comes up a lot and wants the feature more primitively, I
could understand that.
If you were going to suggest new condition types, I would suggest doing
it under separate cover so as to decouple it from this issue, which I
think has the simpler solution described above.
I would not use terms like NOTICE, ALERT, etc. because I think people
will not like our locking down so many highly generic words. Furthermore,
I think you'd have a hard time making a serious case that there was a
need for that particular number of gradations without some experience to
back it up. In my opinion, it would be better at this point to gain
some experience in real implementations and then to suggest things like
this on the next standardization cycle.
Even so, I would expect that the most likely to be adopted types would
be subtypes of WARNING, not disjoint types. eg, STYLE-WARNING. Making
them subtypes of WARNING means you can use WARN without introducing a
new primitive. It means you can use MUFFLE-WARNING without introducing
other MUFFLE-xxx things. Simpler. Little or no lost functionality.
∂27-Dec-88 1204 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 27 Dec 88 12:03:58 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00427g; Tue, 27 Dec 88 01:20:19 PST
Received: by bhopal id AA01703g; Tue, 27 Dec 88 01:20:59 PST
Date: Tue, 27 Dec 88 01:20:59 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812270920.AA01703@bhopal>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: Kent M Pitman's message of Fri, 23 Dec 88 15:43 EST <881223154306.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Subject: issue SHARP-COMMA-CONFUSION, version 1
re: In Cost To Users, the DEFPARAMETER technique described has been
demonstrated to be unacceptable for the general problem.
Although it's probably moot, I strongly object to wording like this,
especially "demonstrated". Such an unproven allegation not only hinders
a clear assessment of the problem at hand ("Cost to Users"), but muddies
the thinking for other issues. Suffice it to say that nearly everyone
who favors flushing #, does so on the assumption that some version of
LOAD-TIME-EVAL will be passed; so the two issues are tightly linked.
A performance allegation on this point was made some time ago in the mails,
but **no** facts or figures were ever adduced. This kind of statement is
not purely philosophical -- one that only needs "clever" arugmentation --
it needs facts.
The continual repetition of the allegation does nothing whatsoever to
verify it.
-- JonL --
∂27-Dec-88 1206 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, V3
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 27 Dec 88 12:06:11 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00367g; Mon, 26 Dec 88 23:20:58 PST
Received: by bhopal id AA01499g; Mon, 26 Dec 88 23:21:38 PST
Date: Mon, 26 Dec 88 23:21:38 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812270721.AA01499@bhopal>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: Kent M Pitman's message of Thu, 22 Dec 88 19:47 EST <881222194753.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Subject: issue COMPILER-LET-CONFUSION, V3
re: I've made a case that it [COMPILER-LET] expresses a useful high level
concept and that it can be coherently implemented. . . .
And many of us don't buy that argument. Furthermore, I don't think the
current msg you sent advances the discussion any.
[Kent, you can do much better when you don't "go meta". In particular
your generalization of the CL-Cleanup activity:
"In general, Cleanup
does not drop alternative proposals unless they can achieve consensus
that it is not worth pursuing the alternate proposals."
makes it sound as if there is some impersonal god named "Cleanup" who,
working according to inexorable natural laws, ensures total fairness and
completeness. It just isn't like that. "Cleanup" consists of a lot of
very highly opinionated humans, who repeatedly make their voices heard,
just as you are now making your's heard on CL-Compiler.]
It's not unheard of that a *single* dissenting member of a sub-committee
has later swayed the whole sub-committee to his view. Similarly, when
these issues are discussed, "bundled" or otherwise, at X3J13 plenary
sessions, any X3J13 member who feels strongly enough on any issue can
move to reject the sub-committee's proposal and substitute a solution
of his own. Considering that *very few* members of the whole committee
have been commenting on issues -- CL-Compiler or CL-Cleanup -- then
I wouldn't be a bit surprised if this happens.
When there seems to be consensus on an issue, on either discussion list,
it *does not* mean that everyone agrees; it can simply mean that those who
disagree don't feel the alternatives are so bad as to be worth wasting more
time on. At this stage of the game, I think we must consider objections
primarily at the level of "is absolutely unacceptable".
Do you really feel that the next version of CL will be "absolutely
unacceptable" if it doesn't have COMPILER-LET in it?
-- JonL --
∂27-Dec-88 1216 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 27 Dec 88 12:15:55 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00234g; Mon, 26 Dec 88 16:16:28 PST
Received: by bhopal id AA00771g; Mon, 26 Dec 88 16:17:08 PST
Date: Mon, 26 Dec 88 16:17:08 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812270017.AA00771@bhopal>
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Cc: @sail.stanford.edu:jonl@lucid.com, @cs.utah.edu:sandra@defun,
cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton's message of Fri, 23 Dec 88 19:36:04 GMT <21484.8812231936@subnode.aiai.ed.ac.uk>
Subject: issue QUOTE-MAY-COPY, version 2
Ok, I see you point. The issue finally boils down to this:
"Is the preservation of EQLness for quoted constants so important
as to be the sole cause of yet another incompatibility between
code compiled by COMPILE-FILE and code compiled by COMPILE?"
As you might have guessed, I favor giving as much leeway as possible to
the implementors for making memory-management optimizations. While one
implementor may choose not to do any such work, and another may even go
out of his way to assure EQLness over an unlikely set of circumstances,
this should not constrain the third from doing the "classic" thing. In
short, I don't see the value of adding constraints that
(1) invalidate much existing practice, and
(2) appear to be purely of theortical value.
Making "compiled code" (read: compile-file) work as closely as possible to
interpreted code is _not_ "purely of theortical value."
QUOTE-MAY-COPY:ALWAYS is the only proposal that both recognizes the
prevalent practice and pays (at least) lip service to the question of
compiled/interpreted consistency.
-- JonL -
∂27-Dec-88 1705 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
Received: from SAPSUCKER.SCRC.Symbolics.COM ([128.81.41.223]) by SAIL.Stanford.EDU with TCP; 27 Dec 88 17:05:25 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 266674; Tue 27-Dec-88 16:43:33 EST
Date: Tue, 27 Dec 88 16:42 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue SHARP-COMMA-CONFUSION, version 1
To: jonl@lucid.com
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, sandra%defun@cs.utah.edu,
cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: <8812270920.AA01703@bhopal>
Message-ID: <881227164231.7.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Tue, 27 Dec 88 01:20:59 PST
From: Jon L White <jonl@lucid.com>
re: In Cost To Users, the DEFPARAMETER technique described has been
demonstrated to be unacceptable for the general problem.
Although it's probably moot, I strongly object to wording like this,
especially "demonstrated". Such an unproven allegation not only hinders
a clear assessment of the problem at hand ("Cost to Users"), but muddies
the thinking for other issues. Suffice it to say that nearly everyone
who favors flushing #, does so on the assumption that some version of
LOAD-TIME-EVAL will be passed; so the two issues are tightly linked.
A performance allegation on this point was made some time ago in the mails,
but **no** facts or figures were ever adduced. This kind of statement is
not purely philosophical -- one that only needs "clever" arugmentation --
it needs facts.
The continual repetition of the allegation does nothing whatsoever to
verify it.
I had alluded to the fact that I use this in my every-day programming.
I didn't supply actual numbers, but I didn't mean to suggest that there were
no such numbers. I just wasted over an hour of my very valuable time dredging
them up. This had better close discussion on this issue:
The Cloe Window System is written in a flavors implementation similar
to CLOS, and uses a facility similar to LOAD-TIME-VALUE.
For example, there are 135 classes in the Cloe Window System. There are
1340 methods, an average of ten per class. There are generally at least
two references to LOAD-TIME-VALUE per method.
I'll assume that the minimum size of a symbol is 4 words (one for package
pointer, one for a (presumably null) plist, one for a function cell
(presumably undefined), and one for a value cell. Typical implementations
indirect that cell to a cell elsewhere which is the actual value cell, so
add another word. Also add a word or two for the pname. So we're talking
6 words for each symbol itself. Also, these symbols are interned, so I'll
add another two words for the hash table overhead. 8 words.
That's 8 words times 2680 references, or 21,440 words of totally wasted
space.
Now let's back up and look at it another way.
'X typically compiles to an immediate move and does not take a page fault.
A special X reference may take a page fault, and in any case compiles to
a non-immediate move.
eg, consider:
(defvar foo1 2)
(defun foo1 () foo1)
(defun foo2 () '#,(+ 1 1))
Under Genera:
(disassemble 'foo1)
0 ENTRY: 0 REQUIRED, 0 OPTIONAL
1 PUSH-INDIRECT FOO1
2 RETURN-STACK
(disassemble 'foo2)
0 ENTRY: 0 REQUIRED, 0 OPTIONAL
1 PUSH-IMMED 2
2 RETURN-STACK
Under Cloe on a 386:
(disassemble 'foo1)
...
movl [FOO1], esi
movl -2(esi), eax
[optional error checking]
...
(disassemble 'foo2)
...
movl [2], eax
...
So every time we execute one of these references, we're running slower if
we're taking the reference through a special variable rather than
immediately.
Time lost unnecessarily.
Space lost unnecessarily.
∂29-Dec-88 0312 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 29 Dec 88 03:12:08 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00885g; Thu, 29 Dec 88 03:07:20 PST
Received: by bhopal id AA09875g; Thu, 29 Dec 88 03:09:30 PST
Date: Thu, 29 Dec 88 03:09:30 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812291109.AA09875@bhopal>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Cc: sandra%defun@cs.utah.edu, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kent M Pitman's message of Tue, 27 Dec 88 16:42 EST <881227164231.7.KMP@BOBOLINK.SCRC.Symbolics.COM>
Subject: issue SHARP-COMMA-CONFUSION, version 1
re: [Statistics] I just wasted over an hour of my very valuable time
dredging them up. This had better close discussion on this issue:
The "numbers" on total number of symbols elided from the Cloe window
system are indeed impressive; but there are no numbers on "time
wasted" [is it because the sum total of "wasted" time is a truly a
negligible portion of any application's time?] On the other hand,
as I said before, the whole question is moot:
(1) The proposals are to flush sharp-comma, and replace it with the
non-equivalent LOAD-TIME-EVAL. So far, no one believes that
the proposed new feature cannot suffice for their needs, so
there is no reason to retain the broken sharp-comma.
(2) The Cloe window system code was surely written with the known
availability of sharp-comma; who's to say what the code would
have looked like had it been written without that availability.
Would it really have used 26000 spurious symbols? and would
that be the only source of tens of thousands of spurious symbols
[Please! don't even spend 60 seconds trying to answer that].
I know that Lucid Lisp has a step that reclaims several thousand
symbols, very very few of which were used as "temporary
defparameters" (yes, we *have* to do the step, regardless of
sharp-comma); nevertheless, any such "wasted symbols" could
be reclaimed by this kind of technique, after the system had
been completely loaded and "snapped".
To reiterate my main point, none of these allegations -- substantiated or
not -- belong in the "Cost to Users" section. At best they should be put
into the discussion section, where they can continue to foster frutiless
debates. This "Cost" section should link to the LOAD-TIME-EVAL issue,
and assess the cost of conversion to that format; I think Sandra has
already done a reasonable job of offering a conversion paradigm that will
fit most cases.
-- JonL --
∂29-Dec-88 0500 Common-Lisp-Object-System-mailer Compilation implications
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 29 Dec 88 04:54:06 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00911g; Thu, 29 Dec 88 04:50:36 PST
Received: by bhopal id AA10083g; Thu, 29 Dec 88 04:52:47 PST
Date: Thu, 29 Dec 88 04:52:47 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812291252.AA10083@bhopal>
To: Common-Lisp-Object-System@Sail.Stanford.edu
Cc: CL-Compiler@Sail.Stanford.edu
Subject: Compilation implications
This somewhat long msg has questions aobut two issues in it:
(A) "Reconstructor" functions for instances
(B) References to classes "by name"
Partly I would like an answer to them to aid in development at Lucid,
and partly to help resolve lingering issues in the CL-Compiler's work
on quoted constants.
(A) "Reconstructor" functions for instances
We at Lucid are getting more and more requests for a coherent "Reconstructor"
protocol (well, they are usually couched in ill-advised terms about making
FASLOUT user-extensible, but we've already seen this issue before). Does
anyone have any plans to work on this problem? Didn't someone recently
say that Symbolics has some possibly-private Reconstructor capability?
What is the feeling about the Symbolics facility (I don't know anything
about it).
One might ask, "How do ``instances'' come to the attention of FASLOUT?"
They can appear as a quoted constant; hence, Cris Perdue's query:
Date: Mon, 14 Nov 88 11:54:29 PST
From: cperdue@Sun.COM (Cris Perdue)
To: cl-object-oriented-programming@sail.stanford.edu
Subject: Standard-objects in quoted constants
to which Moon replied later that day about the need for a reconstructor
protocol. I should think it rare for quoted instances to appear directly
in code files. But there are some important exceptions that, indirectly,
introduce "constants" into a file; for example, the use of #. to emulate
a FASDMP facility; and also macro-generated code that produces otherwise
unREADable forms. If the semantics of DEFCONSTANT were more "hard-wired",
then it too would be such an exception. ["hard-wired" means that the value
at run time is that obtained by evaluating the defconstant form at compile
time, rather than by evaluating the form at load time; it would mean that
(defconstant foo (bar)) is similar to (defconstant foo (quote #.(bar))).]
Possibly, EQL specializers could raise this question. Upon re-reading,
the language of 88-002R now seems a bit vague to me, and possibly open
to misinterpretation, as to just when an EQL parameter specializer form
is evaluated. Consider the similarity with DEFCONSTANT. The language
in CLtL about DEFCONSTANT seems to imply, to most people, that the runtime
environment ought to have a special variable that holds the "constant"
value (references to which are allowed to be "snapped" in compiled code);
and that the value of this variable is set at load time, when the defining
form's "form" is evaluated, just like it would be for defparameter. [Hence
DEFCONSTANT doesn't define a compile-time constant in the same way that
conventional language compilers do.] The various implementations I've
looked at so far seem to do it this way -- they do an evaluation at load
time (typically, by executing a "thunk") to produce the constant's value.
The language of 88-002R doesn't seem to rule out either way of obtaining
the "object"-- producing a thunk or producing a compile-time constant.
The only relevant difference is that it prescribed the evaluation to be
done in the lexical environment of the defining form, which for
COMPILE-FILE simply means that the "thunk" is compiled in that lexical
environment. But has anyone wanted the more "hardwired" version?
(B) References to classes "by name"
The analogy between FIND-PACKAGE and FIND-CLASS suggests that class
objects are in the same "database" category as packages. Shouldn't
they be referenced "by name" in compiled file? Lucid has been fasl'ing
out packages for some time merely "by reference"; the culmination of the
CL-Compiler's deliberations on "quoted constants in compiled files" seems
to be that this is the only reasonable meaning for reference to a "quoted
package". Are there any other implementations that do otherwise for
"quoted" classes?
I realize this may pose some ordering constraints on the executions in a
file, if the compiled version is to operate correctly -- i.e., classes might
have to be defined before the use of any constant that "names" that class.
Such constraints may not be as feasible as they are in the package world
(Indeed, some folks even dislike the package ordering constraints!). Can
a forward-reference, "placeholder" be substituted for a class that hasn't
yet been defined, but is referenced by a quoted constant?
-- JonL --
∂29-Dec-88 0654 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 29 Dec 88 06:53:20 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 513042; Thu 29-Dec-88 09:47:11 EST
Date: Thu, 29 Dec 88 09:46 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue SHARP-COMMA-CONFUSION, version 1
To: jonl@lucid.com
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, sandra%defun@cs.utah.edu,
cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: <8812291109.AA09875@bhopal>
Message-ID: <881229094643.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Thu, 29 Dec 88 03:09:30 PST
From: Jon L White <jonl@lucid.com>
The "numbers" on total number of symbols elided from the Cloe window
system are indeed impressive; but there are no numbers on "time
wasted" [is it because the sum total of "wasted" time is a truly a
negligible portion of any application's time?]
I gave you the comparative instruction sequences for the 3600 and 386.
In the case of the 3600, a slower instruction is used. In the case of
the 386, an extra instruction is used. The cost depends on your
application, but people are so benchmark-conscious these days that
I don't think it's something we can ignore.
....
(1) The proposals are to flush sharp-comma, and replace it with the
non-equivalent LOAD-TIME-EVAL. So far, no one believes that
the proposed new feature cannot suffice for their needs, so
there is no reason to retain the broken sharp-comma.
Right. I was just making the point that the two proposals need some
explicit tie, so it doesn't turn out by quirk of fate that we kill #,
and don't pass LOAD-TIME-EVAL.
(2) The Cloe window system code was surely written with the known
availability of sharp-comma; who's to say what the code would
have looked like had it been written without that availability.
Would it really have used 26000 spurious symbols?
This isn't a fair question. I was addressing only the claim in this
proposal that using defparameter was an adequate workaround. Indeed it
is not, and Cloe would have done something else. My point was that
whatever we'd have done instead would probably be considerably harder to
think up than any of the simple-minded workarounds presented in the
writeup. The writeup needs to either cite serious workarounds or come
out and say "Gosh, you'd be in a real bind if we removed this without
providing something equivalent, like the LOAD-TIME-EVAL proposal. Here
are a few simple things that work sometimes, but in the hard cases
we just don't have any idea what you might try."
... and would
that be the only source of tens of thousands of spurious symbols
To paraphrase some well-known congressman: A few 100K here a few 100K there,
pretty soon it starts to add up to real address space...
[Please! don't even spend 60 seconds trying to answer that].
I know that Lucid Lisp has a step that reclaims several thousand
symbols, very very few of which were used as "temporary
defparameters" (yes, we *have* to do the step, regardless of
sharp-comma); nevertheless, any such "wasted symbols" could
be reclaimed by this kind of technique, after the system had
been completely loaded and "snapped".
This mystifies me. As I understand it, these defparameters can't be snapped
because you can't prove they won't be SETQ'd. So you can't reclaim them as
dead symbols.
To reiterate my main point, none of these allegations -- substantiated or
not -- belong in the "Cost to Users" section. At best they should be put
into the discussion section, where they can continue to foster frutiless
debates. This "Cost" section should link to the LOAD-TIME-EVAL issue,
and assess the cost of conversion to that format; I think Sandra has
already done a reasonable job of offering a conversion paradigm that will
fit most cases.
I don't care what allegations in Cost or not. I'd be content for that
section to be smaller -- I just want it to be honest. The workarounds it
cites are fine for a few simple cases, but do not scale up to serious
applications. There is no fair way to say if "most" is an appropriate
way of quantifying the cases where it works. As such, I'd avoid any such
term and just say plainly that the cited techniques aren't adequate for
the general case. Let the reader decide for him- or herself.
Also, I just think as a point of style, we cannot limit the Cost
discussion to the cost of conversion to LOAD-TIME-EVAL unless we have
voted in LOAD-TIME-EVAL. But it's ok with me if we limit the discussion
of the Cost in the other case to a simple sentence: "If LOAD-TIME-EVAL
doesn't pass, of course, doing without #, will be very much harder; no
simple set of workarounds has been suggested which deal with all current
uses of #, in the absence of the new LOAD-TIME-VALUE special form.".
∂29-Dec-88 1001 Common-Lisp-Object-System-mailer Compilation implications
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 29 Dec 88 10:01:43 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 513111; Thu 29-Dec-88 12:59:40 EST
Date: Thu, 29 Dec 88 12:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Compilation implications
To: Jon L White <jonl@lucid.com>
cc: Common-Lisp-Object-System@Sail.Stanford.edu, CL-Compiler@Sail.Stanford.edu
In-Reply-To: <8812291252.AA10083@bhopal>
Message-ID: <19881229175913.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
[Responding to only one portion of your message]
Date: Thu, 29 Dec 88 04:52:47 PST
From: Jon L White <jonl@lucid.com>
(A) "Reconstructor" functions for instances
We at Lucid are getting more and more requests for a coherent "Reconstructor"
protocol (well, they are usually couched in ill-advised terms about making
FASLOUT user-extensible, but we've already seen this issue before). Does
anyone have any plans to work on this problem? Didn't someone recently
say that Symbolics has some possibly-private Reconstructor capability?
What is the feeling about the Symbolics facility (I don't know anything
about it).
It's very simple and effective. There is a generic function (never mind its
name, the current stupid name was chosen about a dozen years ago) that is
applied to one argument and returns a Lisp form. The intent is that when
that form is evaluated at some later time, it should return an object that
is equivalent to the argument. Using EVAL provides full generality. Of
course the compiler/fasdumper/fasloader is allowed to optimize special-case
forms that it recognizes, rather than always calling EVAL at load time.
This generic function is supported for standard-object and structure-object
(using CLOS terminology). A good name would be MAKE-RECONSTRUCTION-FORM or
perhaps MAKE-LOAD-FORM (why introduce a new word "reconstruct" when we
already have the word "load" which really means the same thing?).
In addition, there is a level of protocol built on top of this that some
things use. There is a mixin flavor that provides a method for the
first generic function; it returns a form that calls MAKE-INSTANCE with
(TYPE-OF SELF) as the first argument, and the remaining arguments
obtained by calling another generic function whose methods' results are
usually combined with APPEND. This provides a convenient way for
multiple classes to contribute to the reconstruction of an object;
each class supplies the initargs that are relevant to that class.
I'd suggest MAKE-LOAD-INITARGS for the name of this generic function
and LOAD-USING-INITARGS-MIXIN for the name of the class. I haven't put
a great deal of thought into these names.
There is also a method that uses the simple-minded reconstruction
technique of just looking at the slots that have :INITARGs and calling
MAKE-INSTANCE with the reconstructed values of those slots.
An important thing to realize is that the default for a standard-object
is to signal an error; there is no default method on standard-object
for either of these generic functions. That's important because no
default reconstruction method can be correct for all objects, and we
feel it's better to make the programmer pick a method explicitly than
to supply a default that might just make trouble.
I don't remember why the CLOS committee didn't put anything like this
into the proposed standard. Maybe we thought it was the Compiler
committee's business, maybe we had some disagreement, or maybe we
just ran out of time.
One might ask, "How do ``instances'' come to the attention of FASLOUT?"
They can appear as a quoted constant; hence, Cris Perdue's query:
Date: Mon, 14 Nov 88 11:54:29 PST
From: cperdue@Sun.COM (Cris Perdue)
To: cl-object-oriented-programming@sail.stanford.edu
Subject: Standard-objects in quoted constants
to which Moon replied later that day about the need for a reconstructor
protocol. I should think it rare for quoted instances to appear directly
in code files. But there are some important exceptions that, indirectly,
introduce "constants" into a file; for example, the use of #. to emulate
a FASDMP facility; and also macro-generated code that produces otherwise
unREADable forms.
Rare, but not unheard of. Note also two other common sources of non-built-in
type objects in compiled-code files: 1. Any type that has a read syntax is
likely to appear as a quoted constant or inside a quoted constant. Pathnames
are one example, user programs often define others. 2. Symbolics has a
facility for creating a compiled-code file full of data (rather than compiled
Lisp programs), which is convenient because it's an efficient binary file
that you can load with LOAD instead of having to write your own loader.
(This can be simulated in any Common Lisp implementation by creating a dummy
file that consists of just one call to a special macro, defining the macro
to expand into forms to put the data where you want it, then using COMPILE-FILE
on that dummy file).
Most of the rest of your message concerns the metaobject protocol and I can't
answer it. I'll just note that in Flavors we generate metaobjects at compile
time, but we never put them (to speak loosely) into the compiled-code file;
instead macros like DEFFLAVOR and DEFMETHOD expand into Lisp code that obtains
new metaobjects at load time, based on the class name and generic function name.
I don't see how any other way could work, actually, since two distinct compiled
files that refer to a class by the same name must end up referring to the
same metaobject after loading. In Flavors we don't have anonymous classes nor
anonymous generic functions, so we don't have to solve those issues.
∂29-Dec-88 1804 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
Received: from ti.com by SAIL.Stanford.EDU with TCP; 29 Dec 88 18:04:28 PST
Received: by ti.com id AA06848; Thu, 29 Dec 88 20:03:50 CST
Received: from dsg by tilde id AA23842; Thu, 29 Dec 88 19:52:10 CST
Received: From Kelvin By dsg Via CHAOS-NET With CHAOS-MAIL; Thu, 29 Dec 88 19:49:57 CST
Message-Id: <2808438777-7471948@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 29 Dec 88 19:52:57 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
In-Reply-To: Msg of Fri, 16 Dec 88 15:32:10 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> DEFVAR, DEFPARAMETER: The compiler must recognize that the variables
> named by these forms have been proclaimed special. However, the it
> must not evaluate the initial value or SETQ the variable at compile
> time.
On the second line, "the it" -> "it".
> DEFSTRUCT: The compiler must make the structure type name recognized
> as a valid type name in subsequent declarations (as for DEFTYPE) and
> make the structure slot accessors known to SETF. In addition, the
> compiler must save enough information about the structure type so that
> further DEFSTRUCT definitions can :INCLUDE a structure type defined
> earlier in the file being compiled. The functions which DEFSTRUCT
> generates are not defined at compile time.
Shouldn't that last sentence say something like "... need not be defined
..."? Since the accessor functions commonly default to INLINE, they
often will be defined at compile time.
> DEFCLASS, DEFMETHOD, DEFGENERIC, DEFINE-METHOD-COMBINATION: More input
> is needed from the CLOS committee to decide what to do with these
> macros.
Since I've been working on compiler updates for supporting CLOS, let me
take a stab at this:
DEFCLASS: The compiler must make the class name be recognized as a
valid type name in subsequent declarations (as for DEFTYPE) and be
recognized as a valid class name for DEFMETHOD parameter
specializers and for use as the :METACLASS option of a subsequent
DEFCLASS. The compiler must make the class definition available to
be returned by FIND-CLASS when its environment argument is a value
received as the &ENVIRONMENT parameter of a macro.
DEFGENERIC and DEFMETHOD: These are not required to perform any
compile-time side effects. In particular, the methods are not
installed for invocation during compilation. An implementation may
choose to store information about the generic function for the
purposes of compile-time error-checking (such as checking the number
of arguments on calls, or noting that a definition for the function
name has been seen).
DEFINE-METHOD-COMBINATION: The compiler is not required to perform
any compile-time side-effects.
∂29-Dec-88 2213 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 29 Dec 88 22:12:57 PST
Received: from GANG-GANG.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254794; Fri 30-Dec-88 00:31:19 EST
Date: Fri, 30 Dec 88 00:30 EST
From: Glenn S. Burke <gsb@ALDERAAN.SCRC.Symbolics.COM>
Subject: Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
To: Gray@DSG.csc.ti.com, sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <2808438777-7471948@Kelvin>
Message-ID: <19881230053057.5.GSB@GANG-GANG.SCRC.Symbolics.COM>
Date: Thu, 29 Dec 88 19:52:57 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> DEFSTRUCT: The compiler must make the structure type name recognized
> as a valid type name in subsequent declarations (as for DEFTYPE) and
> make the structure slot accessors known to SETF. In addition, the
> compiler must save enough information about the structure type so that
> further DEFSTRUCT definitions can :INCLUDE a structure type defined
> earlier in the file being compiled. The functions which DEFSTRUCT
> generates are not defined at compile time.
Shouldn't that last sentence say something like "... need not be defined
..."? Since the accessor functions commonly default to INLINE, they
often will be defined at compile time.
That doesn't follow: they only need to be properly compiled, not executed.
Having something be defined just so it can be inlineable can be a bad idea.
Similarly, i'd suggest that wording similar to that used below that i have
marked be used for describing the availability of slots to SETF, so as to not
imply that compilation of a defsetf must side-effect the runtime environment.
> DEFCLASS, DEFMETHOD, DEFGENERIC, DEFINE-METHOD-COMBINATION: More input
> is needed from the CLOS committee to decide what to do with these
> macros.
Since I've been working on compiler updates for supporting CLOS, let me
take a stab at this:
DEFCLASS: The compiler must make the class name be recognized as a
valid type name in subsequent declarations (as for DEFTYPE) and be
recognized as a valid class name for DEFMETHOD parameter
specializers and for use as the :METACLASS option of a subsequent
-> DEFCLASS. The compiler must make the class definition available to
-> be returned by FIND-CLASS when its environment argument is a value
-> received as the &ENVIRONMENT parameter of a macro.
∂30-Dec-88 0108 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 1
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 30 Dec 88 01:08:24 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01480g; Fri, 30 Dec 88 01:04:43 PST
Received: by bhopal id AA13419g; Fri, 30 Dec 88 01:06:52 PST
Date: Fri, 30 Dec 88 01:06:52 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812300906.AA13419@bhopal>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kent M Pitman's message of Thu, 29 Dec 88 09:46 EST <881229094643.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
Subject: issue SHARP-COMMA-CONFUSION, version 1
Well, you're right that the link between proposals needs to be made explicit.
At the risk of beating an old horse, I think the only way LOAD-TIME-EVAL
can fail to pass is that a technical deadline falls before the polished
wording is achived. Nevertheless, I would still recommend flusing #, from
the portable language even if that horrible event occurs. If we should be
left with neither LOAD-TIME-EVAL nor #, I would claim that we are *still*
better off than the current situation:
-- The current situation is that #, is an inherently broken idea,
never minding that some limited usages of it get around the lack
of LOAD-TIME-EVAL (I refer to previous discussion about the
impossibility of getting a fully consistent definition for #,)
Praising the portabililty of something that can't work as expected
even in one implementation does no good to "portability" nor to
the broken hack.
-- A bad situation (but possibly preferable to the current) is that
there is no portable way to do LOAD-TIME-EVAL; no system code would
be broken by that (I doubt that you are porting the Cloe window
system to GCL), and few if any portable application programs would
be broken (remember how Gregor gave up the use of #,).
-- The better situation is to convince all #, users that any reasonable
use of it can be covered by LOAD-TIME-EVAL. Probably unreasonable
uses can't be converted. So who cares. We could give some help to
Sandra in collecting conversion paradigms for "reasonable" uses.
-- JonL --
∂30-Dec-88 0400 CL-Compiler-mailer Compilation implications
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 30 Dec 88 03:48:39 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01516g; Fri, 30 Dec 88 03:44:28 PST
Received: by bhopal id AA13748g; Fri, 30 Dec 88 03:46:40 PST
Date: Fri, 30 Dec 88 03:46:40 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812301146.AA13748@bhopal>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: Common-Lisp-Object-System@Sail.Stanford.edu, CL-Compiler@Sail.Stanford.edu
In-Reply-To: David A. Moon's message of Thu, 29 Dec 88 12:59 EST <19881229175913.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Compilation implications
Thanks for your many comments, Dave. I'm sure they will be useful.
re: ["Reconstructor" forms and mixins]
I don't remember why the CLOS committee didn't put anything like this
into the proposed standard. Maybe we thought it was the Compiler
committee's business, maybe we had some disagreement, or maybe we
just ran out of time.
There is a blend of problems here -- partly object-oriented and partly
semantics of compilation. It could be that the buck is getting shuffled
back and forth and nothing being done. Maybe the time just wasn't ripe
for specifying this protocol -- maybe more experience is needed -- but
sooner or later the user-community will be "push coming to shove" and
the lack of a portable interface could be damaging.
re: [fasling out classes "by name"]
I don't see how any other way could work, actually, since two distinct
compiled files that refer to a class by the same name must end up
referring to the same metaobject after loading.
Right. Separate compilation seems to be the clinching argument.
-- JonL --
∂30-Dec-88 0533 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 30 Dec 88 05:33:13 PST
Received: from relay2.cs.net by RELAY.CS.NET id ab27237; 30 Dec 88 8:18 EST
Received: from draper.com by RELAY.CS.NET id aa28002; 30 Dec 88 8:11 EST
Date: Fri, 30 Dec 88 07:50 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER,SEB1525
> Date: Thu, 29 Dec 88 19:52:57 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> > DEFSTRUCT: The compiler must make the structure type name recognized
> > as a valid type name in subsequent declarations (as for DEFTYPE) and
> > make the structure slot accessors known to SETF. In addition, the
> > compiler must save enough information about the structure type so that
> > further DEFSTRUCT definitions can :INCLUDE a structure type defined
> > earlier in the file being compiled. The functions which DEFSTRUCT
> > generates are not defined at compile time.
>
> Shouldn't that last sentence say something like "... need not be defined
> ..."? Since the accessor functions commonly default to INLINE, they
> often will be defined at compile time.
>
>That doesn't follow: they only need to be properly compiled, not executed.
>Having something be defined just so it can be inlineable can be a bad idea.
>Similarly, i'd suggest that wording similar to that used below that i have
>marked be used for describing the availability of slots to SETF, so as to not
>imply that compilation of a defsetf must side-effect the runtime environment.
Don't the DEFSTRUCT functions have to be compiled so that is it possible to
have things like
(defstruct foo bar baz)
(let ((a (make-foo)))
(frobulate #'foo-bar a))
...assuming that frobulate is unknown at compile time or otherwise cannot be
expanded inline? This is the basic reason that DEFSTRUCT accessor forms
were changed from macros to functions in CL, right?
∂30-Dec-88 1053 CL-Compiler-mailer I'm back
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Dec 88 10:53:06 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA00998; Fri, 30 Dec 88 11:52:06 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03595; Fri, 30 Dec 88 11:52:04 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812301852.AA03595@defun.utah.edu>
Date: Fri, 30 Dec 88 11:52:03 MST
Subject: I'm back
To: cl-compiler@sail.stanford.edu
I've returned from my vacation to find my mailbox overflowing with 50+
new messages. Thanks to everybody who made suggestions on the various
proposals. I may not get around to acknowledging them all
individually, but I will try to get new versions of the proposals out
to address the problems ASAP.
-Sandra
-------
∂30-Dec-88 1128 CL-Compiler-mailer Re: Compilation implications
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 30 Dec 88 11:28:17 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA17613; Fri, 30 Dec 88 11:30:11 PST
Received: from suntana.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA28437; Fri, 30 Dec 88 11:26:52 PST
Received: from localhost by suntana.sun.com (4.0/SMI-4.0)
id AA09230; Fri, 30 Dec 88 11:27:29 PST
Message-Id: <8812301927.AA09230@suntana.sun.com>
To: Jon L White <jonl@lucid.com>
Cc: Common-Lisp-Object-System@Sail.Stanford.edu, CL-Compiler@Sail.Stanford.edu,
cperdue%suntana@Sun.COM
Subject: Re: Compilation implications
In-Reply-To: Your message of Thu, 29 Dec 88 04:52:47 -0800.
<8812291252.AA10083@bhopal>
Date: Fri, 30 Dec 88 11:27:27 PST
From: kempf@Sun.COM
A couple comments on the original and Moon's followup.
1) I proposed as a strawman awhile back that a read macro be introduced
similar to #S for DEFSTRUCTSs so that CLOS objects could be stored in
readable ASCII form and also so that they could be made persistent.
There was some discussion on the issue but it eventually died out without
a proposal.
2) I think Moon's solution of a constructor form which gets executed using
EVAL at load time is the only possible solution to this problem. In particular,
the semantics of quoted constants implied by CLtL is that only symbols can
be expected to be EQ across a FASDUMP, and only characters and numbers can
additionally be expected to be EQL. This has interesting implications
for EQL specializers. Since the only objects which can be
expected to survive a FASDUMP and remain EQL are symbols,
numbers, and characters, these are the
only objects which make sense to have in a DEFMETHOD form with an EQL
specialized parameter. This makes it important that machinery
be available to add methods to a generic function through a functional
interface, since some of the things one wants to do with EQL methods require
other objects. Part of that machinery is already in Chapter 2
(ADD-METHOD, MAKE-INSTANCE) but part of it is not
(how to make a method function, for example).
3) With regard to using name equivalence for classes across FASDUMP, again,
I largely agree with Moon on this issue, however I'll take the liberty of
extending his comment somewhat, since I think that slot structure needs
to be taken into account. The problem is basically one of how to handle
class or type equivalence of two CLOS objects in FASL files. When the
two objects are FASLed back in, when will their classes be the same?
Because of the restrictions on EQ and EQL, the class objects, themselves,
cannot be FASLed out because they are not guaranteed to be EQL when
FASLed back in. This solution is impractical in any case, since it implies
FASLing out the entire metaobject structure at compile time just to save
a single object. Also, name equivalence only (i.e. the names of the
classes are the same) may not be sufficient, because the number and names of
slots might be changed, and, in order to FASL the object in, there must
be at least as many slots as their were when it was FASLed out. Having
the same slot names is probably also necessary, since it allows a logical
mapping between the slot contents in the FASL file and the object in memory,
as well as the physical constraint of having enough slots to handle the
slot contents. Note that, again, EQLness of slot descriptor objects, or
any other solution not involving symbols won't work. Requiring the same
class precedence list, or that the inheritance of slots match strikes
me as too restrictive, though I could see arguments why it would be desirable.
Alternatively, the class redefinition protocol could be put to good use to
allow the object to redefine its class if the number and names of slots didn't
match. In that case, name equivalence of classes is the only requirement.
Note that this solution handles anonymous classes fine, but not instances
of anonymous classes. In particular, two instances of the same anonymous
class which are FASLed out then in cannot ever have a class object which is EQ
or EQL, since the FASL in code will create two separate instances of the
anonymous class. The only way around this problem is to either change the
semantics of EQ and EQL for CLOS objects or to treat CLOS classes separately
during FASDUMP. Using class and slot name equivalence or just class name
equivalence with the redefinition protocol coming into play when there is
a mismatch between the slot structures seems like an easier solution.
jak
∂30-Dec-88 1132 CL-Compiler-mailer Re: issue COMPILER-DIAGNOSTICS, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Dec 88 11:32:17 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA02632; Fri, 30 Dec 88 12:31:13 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03628; Fri, 30 Dec 88 12:30:15 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812301930.AA03628@defun.utah.edu>
Date: Fri, 30 Dec 88 12:30:13 MST
Subject: Re: issue COMPILER-DIAGNOSTICS, version 7
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 23 Dec 88 17:50 EST
> Date: Fri, 23 Dec 88 17:50 EST
> From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
>
> I think this proposal is unduly complicated.
Actually, I'm inclined to agree with you on this.
> The problem you state could be addressed by the following much simpler
> proposal:
>
> Specify that COMPILE and COMPILE-FILE return a second value, SUCCESS-P.
> Define that compilers are permitted to handle conditions of type ERROR,
> turning them into warnings and continuing to compile as appropriate,
> but that if an error was turned into a warning so that COMPILE or
> COMPILE-FILE could complete its operation, NIL must be returned as the
> second value. The normal successful return value would be T.
This would be an improvement over the current situation, but I'm
concerned that besides possibly not being enough to satisfy the needs
of people who are trying to write portable system-building utilities,
it won't do anything to solve the stated problem, namely how to
suppress useless style warning messages.
> Even so, I would expect that the most likely to be adopted types would
> be subtypes of WARNING, not disjoint types. eg, STYLE-WARNING.
I've been leaning in this direction too.
I think that what we need to do on this issue is come up with one or two
alternative proposals to include in the next version of the writeup, and
distribute that to X3J13 for further discussion. I'll put it on my list of
things to do next week.
-Sandra
-------
∂30-Dec-88 1220 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 30 Dec 88 12:20:22 PST
Received: from GANG-GANG.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254902; Fri 30-Dec-88 15:19:03 EST
Date: Fri, 30 Dec 88 15:18 EST
From: Glenn S. Burke <gsb@ALDERAAN.SCRC.Symbolics.COM>
Subject: Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
To: SEB1525@draper.com, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: The message of 30 Dec 88 07:50 EST from "Steve Bacher (Batchman)" <SEB1525@draper.com>
Message-ID: <19881230201835.6.GSB@GANG-GANG.SCRC.Symbolics.COM>
Date: Fri, 30 Dec 88 07:50 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
> Date: Thu, 29 Dec 88 19:52:57 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> > DEFSTRUCT: The compiler must make the structure type name recognized
> > as a valid type name in subsequent declarations (as for DEFTYPE) and
> > make the structure slot accessors known to SETF. In addition, the
> > compiler must save enough information about the structure type so that
> > further DEFSTRUCT definitions can :INCLUDE a structure type defined
> > earlier in the file being compiled. The functions which DEFSTRUCT
> > generates are not defined at compile time.
>
> Shouldn't that last sentence say something like "... need not be defined
> ..."? Since the accessor functions commonly default to INLINE, they
> often will be defined at compile time.
>
>That doesn't follow: they only need to be properly compiled, not executed.
I guess i should have added "in the compilation environment".
>Having something be defined just so it can be inlineable can be a bad idea.
>Similarly, i'd suggest that wording similar to that used below that i have
>marked be used for describing the availability of slots to SETF, so as to not
>imply that compilation of a defsetf must side-effect the runtime environment.
Don't the DEFSTRUCT functions have to be compiled so that is it possible to
have things like
(defstruct foo bar baz)
(let ((a (make-foo)))
(frobulate #'foo-bar a))
...assuming that frobulate is unknown at compile time or otherwise cannot be
expanded inline? This is the basic reason that DEFSTRUCT accessor forms
were changed from macros to functions in CL, right?
Yes. But
(defstruct foo bar baz)
(defmacro frobnicate (...)
...
(frobulate #'foo-bar a)
...)
an expansion of a call to frobnicate can reasonably fail during
the compilation of a file containing those forms.
I should say this is my opinion on how this sort of stuff should work.
I didn't mean it to sound like i'm clarifying someone else's statements,
although hopefully I am.
∂30-Dec-88 1303 CL-Compiler-mailer issue DEFCONSTANT-SPECIAL, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Dec 88 13:03:02 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA05128; Fri, 30 Dec 88 14:01:59 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03672; Fri, 30 Dec 88 14:01:55 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812302101.AA03672@defun.utah.edu>
Date: Fri, 30 Dec 88 14:01:54 MST
Subject: issue DEFCONSTANT-SPECIAL, version 3
To: cl-compiler@sail.stanford.edu
Here is a new version of the writeup. As per Kent's suggestion, I have
moved the references to the relevant passages from CLtL to the "Problem
Description" section and strengthened the wording to make it more clear
that lexically rebinding constants is an error (not just a bad idea).
Issue: DEFCONSTANT-SPECIAL
References: CLtL p. 68-69, 55-56
Issue DEFCONSTANT-NOT-WIRED
Issue PROCLAIM-LEXICAL
Issue SYNTACTIC-ENVIRONMENT-ACCESS
Issue SPECIAL-VARIABLE-TEST
Category: CLARIFICATION
Edit History: V1, 15 Nov 1988, Sandra Loosemore
V2, 22 Nov 1988, Sandra Loosemore
V3, 30 Dec 1988, Sandra Loosemore
Problem Description:
It is unclear whether DEFCONSTANT is supposed to proclaim the variable
SPECIAL. Page 56 says that symbols defined by DEFCONSTANT "may not be
further assigned to or bound". Page 69 says that "further assignment
to or binding of that special variable is an error" but permits
compilers to "choose to issue warnings about bindings of the lexical
variable of the same name". Does this mean that it is legal (but
perhaps only questionable style) to lexically rebind constants? If
so, this would seem to imply that they must not be proclaimed SPECIAL
(since CLtL provides no way to override a SPECIAL proclamation).
Some people think that DEFCONSTANT is supposed to proclaim the
variable SPECIAL because CLtL says that DEFVAR does, and that
DEFPARAMETER is like DEFVAR, and DEFCONSTANT is like DEFPARAMETER.
Also, the use of the phrase "that special variable" rather than "the
special variable of the same name" might indicate that the variable
really is supposed to be special.
Proposal DEFCONSTANT-SPECIAL:NO:
Clarify that DEFCONSTANT does not proclaim the variable special, but
that it is an error to rebind constant symbols as either lexical or
special variables. (In other words, a reference to a symbol declared
with DEFCONSTANT always refers to its global value.)
Rationale:
If DEFCONSTANT declared the variable special, the lexical rebindings
mentioned on p. 69 could never arise. Clarifying that lexical
rebinding (as well as special rebinding) of constants "is an error"
seems to be the behavior that most users expect. One serious problem
that might arise from allowing constants to be rebound lexically is
that it would not be reliable to include symbolic constants in macro
expansions, because the user might have rebound them to something
else.
Current Practice:
Most implementations apparently proclaim the variable special anyway.
Cost to implementors:
Minor.
Cost to users:
Probably none. Since many implementations do proclaim the variable to
be special (while at the same time forbidding special binding), there
is probably no user code that depends upon lexical rebinding of
DEFCONSTANTs.
Benefits:
An area of confusion in the language is removed.
Discussion:
This issue is primarily a documentation clarification. It arose
during a discussion of what the DEFCONSTANT macro might expand into.
As far as users are concerned, it makes no difference whether
constants are special or lexical, as long as all rebinding is
prohibited. The only situation where the distinction might become
important is if a function is added to the language to test whether a
variable has been proclaimed special.
The "problem description" section of the writeup on issue
PROCLAIM-LEXICAL (version 8) also appears to assume that constants
declared with DEFCONSTANT are not special.
-------
∂30-Dec-88 1304 CL-Compiler-mailer issue ALLOW-LOCAL-INLINE, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Dec 88 13:04:30 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA05309; Fri, 30 Dec 88 14:03:30 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03678; Fri, 30 Dec 88 14:03:27 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812302103.AA03678@defun.utah.edu>
Date: Fri, 30 Dec 88 14:03:26 MST
Subject: issue ALLOW-LOCAL-INLINE, version 4
To: cl-compiler@sail.stanford.edu
This version incorporates some minor changes suggested by Pitman.
Forum: Compiler
Issue: ALLOW-LOCAL-INLINE
References: CLtL p. 156, 159
Related issues: PROCLAIM-INLINE-WHERE
Category: CLARIFICATION
Edit History: 21 Sept. 88 V1 by David Gray
27 Oct. 88 V2 by David Gray - new proposal
9 Nov. 88 V3 by David Gray - expanded problem
description and discussion sections.
30 Dec. 88 V4 by Sandra Loosemore -- suggestions from Pitman
Problem Description:
The proposal PROCLAIM-INLINE-WHERE:BEFORE (which was accepted by X3J13
on 10/12/88) clarifies the use of INLINE proclamations, but there
remains a similar problem with the use of a local (DECLARE (INLINE
...)): how can the compiler expand the function inline if it didn't
know that the necessary information should have been saved when the
function was compiled?
Note that an INLINE proclamation does two things:
(1) It tells the compiler to do extra things when it sees the
function -definition-, to make it possible to code the function
inline.
(2) It tells the compiler to code -calls- to the function inline.
In order for local INLINE declarations to be useful, we need part 1
without part 2.
Proposal ALLOW-LOCAL-INLINE:INLINE-NOTINLINE
Clarify that to define a function FOO which is not INLOINE by default
but for which (DECLARE (INLINE FOO)) will make FOO be locally inlined,
the proper definition sequence is:
(PROCLAIM '(INLINE foo))
(DEFUN foo ...)
(PROCLAIM '(NOTINLINE foo))
The INLINE proclamation preceding the DEFUN ensures that compiler will
save the information necessary for inline expansion, and the NOTINLINE
proclamation following the DEFUN prevents it from being expanded
inline everywhere.
Note that while implementations are never required to perform inline
expansion of function calls, many implementations that do support
inline expansion will not be able to respond to local INLINE requests
if this technique is not followed.
Rationale:
Local INLINE declarations are of little use without some way of
alerting the compiler to the possibility of inline expansion before
the function is compiled. This seems the simplest solution since it
just clarifies existing practice instead of adding a new feature to
the language.
A compiler could use some heuristic to save the definitions of functions
that are short enough to look like good candidates for inline expansion,
but then the user is never sure what to expect. It is possible that a
compiler could simply save all definitions (assuming availability
of adequate storage space) but we shouldn't require that.
Test Cases/Examples:
Given the following input to COMPILE-FILE, does F1 get expanded inline
in F2, and does F3 get expanded inline in F4?
(defun f1 (a) (+ a 100))
(defun f2 (b) (declare (inline f1)) (f1 b))
(proclaim '(inline f3))
(defun f3 (a) (+ a 100))
(proclaim '(notinline f3))
(defun f4 (b) (f3 b)) ;F3 is not inline.
(defun f5 (c) (declare (inline f3)) (f3 c)) ;F3 is locally inline.
(defun f6 (c) (f3 c)) ;The local effect is not
; persistent.
Current Practice:
In the example above, using Symbolics, Lucid, or Explorer, F1 is not
expanded in F2, but F3 is expanded in F5.
Cost to implementors:
None, since this is a clarification in accordance with current
practice.
Cost to users:
None.
Benefits:
Users will be able to use (DECLARE (INLINE ...)) with greater assurance
that it will really do something.
Costs of Non-Adoption:
Users will not know how to reliably request inline expansion on a
local basis. This technique is not obvious, and even the need
for it likely to be apparent only to people who understand something
about how the compiler does inline expansion.
Discussion:
Version 1 of this issue included proposal
ALLOW-LOCAL-INLINE:PROCLAIM-ALLOW-INLINE to make an addition to the
language:
(PROCLAIM '(ALLOW-INLINE foo))
This was met with a lack of enthusiasm since it was pointed out that
the same effect could be obtained by using a combination of INLINE and
NOTINLINE.
This is may not be completely true, however, since people's thinking
about NOTINLINE has evolved in the direction of a declaration that
tells the compiler "assume nothing about this function". Thus, a
NOTINLINE proclamation might suppress some optimizations that would
have occurred if there had never been an INLINE and NOTINLINE.
Ideally, it would be nice to have multiple levels of control instead
of just INLINE or NOTINLINE -- something like:
* always inline
* maybe inline (let the compiler decide)
* just save the definition for possible local inline
* default
* never inline
Pitman has said that he generally approves of the direction of this
proposal, but he has also expressed concerns about how the persistance
of INLINE proclamations may cause confusion when functions are redefined
in an incremental development environment.
-------
∂30-Dec-88 1334 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Dec 88 13:34:23 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06626; Fri, 30 Dec 88 14:33:09 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03700; Fri, 30 Dec 88 14:33:01 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812302133.AA03700@defun.utah.edu>
Date: Fri, 30 Dec 88 14:33:00 MST
Subject: Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 5
To: Jon L White <jonl@lucid.com>
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: Jon L White <jonl@lucid.com>, Wed, 21 Dec 88 20:40:59 PST
> Date: Wed, 21 Dec 88 20:40:59 PST
> From: Jon L White <jonl@lucid.com>
>
> I'm not at all comfortable tying in the definition of "toplevel" to READ.
> In particular, lots of so-called top-level forms are not explicitly read
> in, but rather are constructed up by macros which return something like
>
> `(PROGN (DEFUN ...) (DEFMACRO ...) ...<whatever>...)
The definition in the proposal is intended to cover this case; it does say
that the expansion of a top-level macro is also considered to be top-level.
Perhaps I can word this section better. How about:
- A form read by COMPILE-FILE from the input file is a top-level form.
- Forms within the body of a top-level PROGN or EVAL-WHEN are also
top-level forms.
- The expansion of a top-level macro call is also a top-level form.
To me, this kind of recursive definition seems much simpler than
saying "null lexical environment" and then listing a zillion
exceptions. Top-level implies null lexical environment, but the
reverse is not true.
> re: Specify that top-level forms in a file being
> compiled are guaranteed to be processed sequentially, but the order in
> which subforms of a top-level form are processed by the compiler is
> explicitly left unspecified.
>
> I don't understand the motivation for saying anything at all about the
> order of processing the subforms; in particular, it conflicts with a
> perceived requirement that if (PROGN (A) (B)) is at toplevel, then (A)
> and (B) must be processed " at toplevel" and **in order**.
Oops, I guess I lost the rationale for this when I revised the
proposal. It's to allow compilers to perform certain kinds of
source-to-source transformations that may reorder subforms. In any
case, I think it's reasonable to specify that the bodies of top-level
PROGNs and EVAL-WHENs are processed in order, and the proposal should be
more explicit about that.
-Sandra
-------
∂30-Dec-88 1335 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Dec 88 13:35:41 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06652; Fri, 30 Dec 88 14:34:40 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03717; Fri, 30 Dec 88 14:34:38 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812302134.AA03717@defun.utah.edu>
Date: Fri, 30 Dec 88 14:34:37 MST
Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 3
To: cl-compiler@sail.stanford.edu
This version incorporates some minor wording changes suggested by JonL.
Issue: EVAL-WHEN-NON-TOP-LEVEL
References: CLtL p. 69-70
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CHANGE, CLARIFICATION
Edit History: 6-May-88, V1 by Sandra Loosemore
16 Dec 1988, V2 by Sandra Loosemore (alternate direction)
30 Dec 1988, V3 by Sandra Loosemore (minor wording changes)
Problem Description:
The current description of how the compiler should handle EVAL-WHEN
only makes sense when it appears as a top-level form in the file being
compiled. Is it legitimate for EVAL-WHEN to appear in non-top-level
locations? What does it mean in such places?
Proposal EVAL-WHEN-NON-TOP-LEVEL:IGNORE-COMPILE:
Clarify that EVAL-WHEN may appear both at top-level and at
non-top-level. In non-top-level locations, however, the COMPILE
situation is effectively ignored.
More specifically, when an EVAL-WHEN form is processed by the
interpreter (that is, by the function EVAL), the presence of the EVAL
situation indicates that the body of the EVAL-WHEN should be evaluated
as an implicit PROGN. Otherwise, EVAL-WHEN returns NIL without
evaluating the body. The interpreter ignores the COMPILE and LOAD
situations.
When an EVAL-WHEN form is processed by the compiler:
First, if the situation COMPILE is specified:
- If the EVAL-WHEN form appears at top level (as defined in
proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW), then each of
the forms within the body of the EVAL-WHEN are evaluated by
the compiler in the null lexical environment using the
function EVAL.
- Otherwise, no compile-time evaluation takes place. An
implementation is permitted to signal a warning to indicate
that the compile-time evaluation is being ignored.
Then, if the situation LOAD is specified, then the compiler treats
the body of the EVAL-WHEN form as if it were an implicit PROGN.
If the situation LOAD is not specified, then the compiler should
treat the EVAL-WHEN form as if it were a constant value of NIL.
The compiler ignores the EVAL situation.
Rationale:
Restricting compile-time evaluation to top-level locations prevents
complications resulting from performing the evaluation in the wrong
lexical environment.
The behavior specified for top-level EVAL-WHENs in this proposal
differs slightly from that described in CLtL. In the case where both
COMPILE and LOAD are specified, CLtL indicates that the compile-time
evaluation should be interleaved with normal compiler processing of
each of the forms in the body, while this proposal specifies that the
evaluation of all of the body forms should take place before any of
the normal compiler processing (leading to possible multiple
evaluations in the case of nested EVAL-WHENs). However, it is
unlikely that this would cause serious problems for any user programs.
The nesting behavior of EVAL-WHEN as described in CLtL has been
criticized as overly complicated and hard to understand, while this
proposal is much less complicated.
Allowing implementations to signal a warning when ignoring a
non-top-level EVAL-WHEN allows users to be informed that something
unusual is going on.
Current Practice:
IIM Common Lisp implements this proposal. Kim Barrett contributed the
following code that illustrates their implementation:
(defmacro eval-when (situations &body body &environment env)
(if (not (compiler-environment-p env))
(when (member 'eval situations) `(progn ,@body))
(progn
(when (member 'compile situations)
(if (compiler-at-top-level-p env)
(mapc #'eval body)
(warn "Top-level form encountered at non-top-level.")))
(when (member 'load situations) `(progn ,@body)))))
Cost to implementors:
Probably fairly minor in most implementations.
Cost to users:
Except for the change relating to possible multiple evaluation of
nested EVAL-WHENs, this proposal is a compatible extension.
Benefits:
The behavior of EVAL-WHEN is easier to understand. Making EVAL-WHEN
meaningful at non-top-level locations makes it more generally useful,
for example in the expansion of defining macros.
Discussion:
Proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW provides a definition for
the term "top-level".
-------
∂30-Dec-88 1351 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Dec 88 13:51:40 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA07025; Fri, 30 Dec 88 14:50:36 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03738; Fri, 30 Dec 88 14:50:33 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812302150.AA03738@defun.utah.edu>
Date: Fri, 30 Dec 88 14:50:32 MST
Subject: Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Thu, 29 Dec 88 19:52:57 CST
> Date: Thu, 29 Dec 88 19:52:57 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> Since I've been working on compiler updates for supporting CLOS, let me
> take a stab at this:
This all looks reasonable to me. One thing that concerns me is that
the definition of these macros in the CLOS spec includes a lot of
verbiage about errors being signalled, and it is not clear to me
whether these are supposed to be happen at compile time or run time.
(My guess is that most of them are supposed to happen at run time.)
-Sandra
-------
∂30-Dec-88 1520 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Dec 88 15:20:27 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA10251; Fri, 30 Dec 88 16:19:23 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03778; Fri, 30 Dec 88 16:19:20 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812302319.AA03778@defun.utah.edu>
Date: Fri, 30 Dec 88 16:19:19 MST
Subject: issue SHARP-COMMA-CONFUSION, version 2
To: cl-compiler@sail.stanford.edu
This version of the writeup incorporates suggestions from Kent Pitman.
Forum: Compiler
Issue: SHARP-COMMA-CONFUSION
References: CLtL p. 356
Issue LOAD-TIME-EVAL
Category: CHANGE
Edit History: V1, 17 Oct 1988, Sandra Loosemore
V2, 30 Dec 1988, Sandra Loosemore (comments from Pitman)
Problem Description:
The way the read macro #, is defined in CLtL does not make it clear
that it can only appear inside of (implicitly) quoted structure to
guarantee consistent handling between the interpreter and the
compiler. Examples of inconsistent uses would be #, forms appearing
outside of a QUOTE that expand into list or symbol forms that could be
interpreted as code, or strings that could be interpreted as
documentation strings. Users are even more likely to be confused
because the wording in CLtL compares the behavior of #, to the special
form EVAL-WHEN, which must appear in a for-evaluation position.
#, also presents a serious problem to program-analyzing programs
because evaluation is tied to the reader, rather than the interpreter
or compiler. In theory, this could be handled by altering the read table
to have #, construct a "magic cookie" instead of performing read-time
evaluation and having the code walker examine quoted structures, but I've
never seen this actually done in practice.
Proposal SHARP-COMMA-CONFUSION:REMOVE:
Remove the #, read macro from the language.
Rationale:
Removing #, is simpler than trying to redefine it. Removing it from
the standard, rather than redefining it to mean something else (see
issue LOAD-TIME-EVAL), would allow implementations to continue to
provide it as an extension. (Although CLtL does not appear to
explicitly address the question of whether implementations may extend
the reader syntax, some implementations already provide sharp-sign
read macros other than those described in CLtL, such as #P syntax for
pathnames.)
Current Practice:
#, is not used very frequently, but the functionality it provides is
important in some advanced applications; one such application that has
been cited is CLOS. Maintainers of such applications have generally
expressed a willingness to give up #, only if a suitable alternative
is offered (see issue LOAD-TIME-EVAL).
PSL/PCLS has never bothered to implement #, correctly (it's treated
just like #.), and nobody has ever complained about it being broken.
Cost to implementors:
None.
Cost to users:
Because #, is used so infrequently, most users would probably not even
notice its absence.
Issue LOAD-TIME-EVAL proposes to add a special form that would provide
a somewhat cleaner mechanism for load-time evaluation.
It is also possible to use a global variable to get the similar effect as
#,, although this is sometimes awkward and carries a space and
performance penalty in many implementations.
Benefits:
The language specification is simplified by removing a peculiar
feature of the language that is accessible only through the reader.
Removing #, may also allow simpler strategies for implementing
compiled file loaders to be used.
Discussion:
If this proposal is rejected, the definition of #, in the standard will
still need to be clarified to indicate that #, can only appear in
quoted structure. It should probably also include some mention of the
problems that #, can cause code walkers.
Kent Pitman says:
I approve of the ideas being discussed, but ONLY contingent on
LOAD-TIME-VALUE being introduced.
I am optimistic that LOAD-TIME-EVAL will pass, and so I don't think this
will keep #, from passing, but:
- I want people who vote for this to realize the importance of voting
for LOAD-TIME-EVAL.
- On the off chance LOAD-TIME-EVAL doesn't pass, I want people to have
been warned that the consequences were severe for some major
applications.
- I want the records to reflect the actual rationale people should and
hopefully will be using to make these decisions.
-------
∂30-Dec-88 1601 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Dec 88 16:01:22 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA11493; Fri, 30 Dec 88 17:00:20 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA03797; Fri, 30 Dec 88 17:00:17 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812310000.AA03797@defun.utah.edu>
Date: Fri, 30 Dec 88 17:00:16 MST
Subject: issue LOAD-TIME-EVAL, version 8
To: cl-compiler@sail.stanford.edu
This version incorporates comments from Kent Pitman. The one
substantial change is that the proposal now specifies that macroexpansion
happens at compile time, rather than load time, since I thought Kent
presented a fairly convincing argument for doing so.
Forum: Compiler
Issue: LOAD-TIME-EVAL
References: #, (p. 356), (EVAL-WHEN (LOAD) ...) (p. 69-70)
issue SHARP-COMMA-CONFUSION
Category: ADDITION
Edit history: 06-Jun-87, Version 1 by James Kempf
17-Jul-87, Version 2 by James Kempf
12-Nov-87, Version 3 by Pitman (alternate direction)
01-Feb-88, Version 4 by Moon
(from version 2 w/ edits suggested by Masinter)
06-Jun-88, Version 5 by Pitman
(fairly major overhaul, merging versions 3 and 4)
21-Sep-88, Version 6 by Moon (stripped down)
17-Oct-88, Version 7 by Loosemore (change direction again)
30-Dec-88, Version 8 by Loosemore (tweaks)
Problem description:
Common Lisp provides reader syntax (#,) which allows the programmer
to designate that a particular expression within a program is to be
evaluated early (at load time) but to later be treated as a constant.
Unfortunately, no access to this capability is available to programs
which construct other programs without going through the reader.
Some computations can be deferred until load time by use of EVAL-WHEN,
but since EVAL-WHEN must occur only at toplevel, and since the nesting
behavior of EVAL-WHEN is quite unintuitive, EVAL-WHEN is not a general
solution to the problem of load-time computation of program constants.
Proposal (LOAD-TIME-EVAL:R**2-NEW-SPECIAL-FORM):
Add a new special form, LOAD-TIME-VALUE, which has the following
contract:
LOAD-TIME-VALUE form &optional read-only-p [Special Form]
LOAD-TIME-VALUE provides a mechanism for delaying evaluation of <form>
until the expression is in the "runtime" environment.
If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
performs normal semantic processing such as macro expansion but
arranges for the evaluation of <form> to occur at load time in a null
lexical environment, with the result of this evaluation then being
treated as an immediate quantity at run time. It is guaranteed that
the evaluation of <form> will take place only once when the file is
loaded, but the order of evaluation with respect to the "evaluation"
of top-level forms in the file is unspecified.
If a LOAD-TIME-VALUE expression appears within a function compiled
with COMPILE, the <form> is evaluated at compile time in a null lexical
environment. The result of this compile-time evaluation is treated as
an immediate quantity in the compiled code.
In interpreted code, (LOAD-TIME-VALUE <form>) is equivalent to (VALUES
(EVAL (QUOTE <form>))). Implementations which implicitly compile
(or partially compile) expressions passed to EVAL may evaluate the
<form> only once, at the time this compilation is performed. This is
intentionally similar to the freedom which implementations are given
for the time of expanding macros in interpreted code.
Note that, in interpreted code, there is no guarantee as to when
evaluation of <form> will take place, or the number of times the
evaluation will be performed. Since successive evaluations of the
same LOAD-TIME-VALUE expression may or may not result in an evaluation
which returns a "fresh" object, destructive side-effects to the
resulting object may or may not persist from one evaluation to the
next. It is safest to explicitly initialize the object returned by
LOAD-TIME-VALUE, if it is later modified destructively.
Implementations must guarantee that each reference to a
LOAD-TIME-VALUE expression results in at least one evaluation of its
nested <form>. For example,
(CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
must perform two calls to COMPUTE-IT; although there is only one
unique LOAD-TIME-VALUE expression, there are two distinct references
to it.
In the case of a LOAD-TIME-VALUE form appearing in a quoted expression
passed to EVAL, each call to EVAL must result in a new evaluation of
<form>. For example,
(DEFVAR X 0)
(DEFUN FOO () (EVAL '(LOAD-TIME-VALUE (INCF X))))
is guaranteed to increment X each time FOO is called, while
(DEFUN FOO () (LOAD-TIME-VALUE (INCF X)))
may cause X to be evaluated only once.
The READ-ONLY-P argument designates whether the result can be considered
read-only constant. If NIL (the default), the result must be considered
ordinary, modifiable data. If T, the result is a read-only quantity
which may, as appropriate, be copied into read-only space and/or shared
with other programs. (Because this is a special form, this argument is
-not- evaluated and only the literal symbols T and NIL are permitted.)
Rationale:
LOAD-TIME-VALUE is a special form rather than a function or macro
because it requires special handling by the compiler.
Requiring the compiler to perform semantic processing such as macro
expansion on the nested <form>, rather than delaying all such processing
until load time, has the advantages that fewer macro libraries may need
to be available at load time, and that loading may be faster and result
in less consing due to macroexpansion. If users really want to delay
macroexpansion to load time, this can be done with an explicit call to
EVAL, e.g.
(LOAD-TIME-VALUE (EVAL '(MY-MACRO)))
Allowing the same LOAD-TIME-VALUE to cause its nested <form> to be
evaluated more than once makes simplifies its implementation in
interpreters which do not perform a preprocessing code walk. It also
makes the rules for the time of its processing analogous to those
for macro expansion.
This proposal explicitly does -not- tie LOAD-TIME-VALUE to the #,
read macro. Doing so would be an incompatible change to the definition
of #, (which is reliably useful only -inside- quoted structure,
while LOAD-TIME-VALUE must appear -outside- quoted structure in a
for-evaluation position).
The requirement that LOAD-TIME-VALUE expressions be evaluated once per
reference (rather than once per unique expression) prevents problems
that could result by performing destructive side-effects on a value
that is unexpectedly referenced in more than one place.
Current Practice:
This is an addition to the language and has not yet been implemented.
Cost to Implementors:
In compiled code, (LOAD-TIME-VALUE <form>) is similar to
'#,<form>. Most implementations can probably make use of the same
mechanism they use to handle #, to handle LOAD-TIME-VALUE. Note that
#, does not currently provide a mechanism for dealing with
non-read-only-ness.
Implementing LOAD-TIME-VALUE in the interpreter should be fairly
straightforward, since one simply needs to evaluate the <form> in the
null lexical environment. Implementations that use a preprocessing
code walk in the interpreter to perform macro expansion could process
LOAD-TIME-VALUE forms at that time.
Some code-walkers would have to be taught about this new
special form. Such changes would likely be trivial.
Cost to Users:
Some code-walkers would have to be taught about this new
special form. Such changes would likely be trivial.
Benefits:
Users are given a mechanism that to force evaluation to be delayed
until load time that does not rely on a feature of the reader.
Discussion:
Earlier versions (up to version 7) of this proposal stated that
all semantic processing of the LOAD-TIME-VALUE form should be postponed
until load time.
The semantics of LOAD-TIME-VALUE would be simplified considerably if
the READ-ONLY-P argument were removed and destructive operations on
the result of evaluating <form> prohibited. However, some people feel
that the ability to destructively modify the value is an essential
feature to include.
"Collapsing" of multiple references to the same LOAD-TIME-VALUE
expression could be allowed for read-only situations, but it seems
like it would be more confusing to make it legal in some situations
and not in others.
A number of other alternatives have been considered on this issue,
including:
- A proposal for a new special form that would force evaluation of
the <form> to happen only once. This was rejected because of
implementation difficulties.
- A proposal to add a function making the "magic cookie" used by #,
available to user code. The current proposal does not prevent such
a function from being added, but this approach appeared to have
less support than making the hook available as a new special form.
- A proposal to remove #, entirely (issue SHARP-COMMA-CONFUSION).
- A suggestion to change the behavior of (EVAL-WHEN (LOAD) ...).
Kent Pitman says:
Although I'm willing to take multiple evaluation in the interpreter
as a compromise position, I would like it mentioned in the discussion
that this was only an expedient to getting this issue accepted at all,
and that I'm not really happy about it. I have said that I think a
number of our lingering problems (with EVAL-WHEN, COMPILER-LET, and
this -- for example) are due to the presence of interpreters which do
not do a semantic-prepass at a known time. If I had my way, we would
require a semantic pre-pass and we would then be able to forbid
multiple evaluations even in the interpreter.
-------
∂30-Dec-88 1940 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 7
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 30 Dec 88 19:39:57 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA02025g; Fri, 30 Dec 88 19:35:13 PST
Received: by bhopal id AA15992g; Fri, 30 Dec 88 19:37:25 PST
Date: Fri, 30 Dec 88 19:37:25 PST
From: Jim McDonald <jlm@lucid.com>
Message-Id: <8812310337.AA15992@bhopal>
To: sandra%defun@cs.utah.edu
Cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, sandra%defun@cs.utah.edu,
cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Fri, 30 Dec 88 12:30:13 MST <8812301930.AA03628@defun.utah.edu>
Subject: issue COMPILER-DIAGNOSTICS, version 7
> it won't do anything to solve the stated problem, namely how to
> suppress useless style warning messages.
In the original message I sent which (I think) spurred Pierson's
proposal, I had in mind a related class of messages generated by users
(not the compiler per se), which should be captured by the same
mechanism, e.g.:
;;; NOTE: Compiling file foo.lisp (234 out of 567) at 12:54 30-Dec-88
;;; NOTE: This uses the NEW (11-Nov-88) version of magic-macro.
I envisoned a form like NOTE, analogous to WARN, but the real goals
were just (1) to be able to suppress all such messages without
suppressing any significant warning messages and (2) to be able to
break on such messages, analogous to *break-on-warnings*, since they
often represent good debugging points in the main flow of control.
A user can always craft their own such mechanism, but if they can
piggy-back on an existing mechanism their world is just a bit simpler.
This requires some sort of user-accessible function, condition, etc.,
which Pierson's proposal would provide.
jlm
∂30-Dec-88 2008 CL-Compiler-mailer Compilation implications
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 30 Dec 88 20:08:34 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA02064g; Fri, 30 Dec 88 20:05:01 PST
Received: by bhopal id AA16126g; Fri, 30 Dec 88 20:07:12 PST
Date: Fri, 30 Dec 88 20:07:12 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812310407.AA16126@bhopal>
To: kempf@Sun.COM
Cc: Common-Lisp-Object-System@Sail.Stanford.edu, CL-Compiler@Sail.Stanford.edu,
cperdue%suntana@Sun.COM
In-Reply-To: kempf@Sun.COM's message of Fri, 30 Dec 88 11:27:27 PST <8812301927.AA09230@suntana.sun.com>
Subject: Compilation implications
I'll address only the comments you have under item (3).
re: name equivalence only (i.e. the names of the
classes are the same) may not be sufficient, because the number and names
of slots might be changed, and, in order to FASL the object in, there must
be at least as many slots as their were when it was FASLed out. Having
the same slot names is probably also necessary, since it allows a logical
mapping between the slot contents in the FASL file and the object in
memory, as well as the physical constraint of having enough slots to
handle the slot contents.
Well, at load time you could just assuming that a compile-time reference
to a class named FOO is not inconsistent with the class named FOO existing
at load time. [I was more worried about forward references in the compiled
file, that weren't "forward" when the compile-time environment was built --
happens e.g. when you load things out of order].
Part of what you are suggesting could be compared, by analogy, to the
package case. Lucid currently only dumps the name reference; but you
are saying for example that it could also dump the names of all "used"
packages just as a consistency check. Unfortunately, I don't see how
to evaluate the myriads of consistency checks that could conceivable be
placed in a "dumped" class; would they be worth the effort?
re: In particular, two instances of the same anonymous
class which are FASLed out then in cannot ever have a class object which
is EQ or EQL, since the FASL in code will create two separate instances
of the anonymous class.
This is not a problem in Lucid Common Lisp [by the bye, I'm assuming a
single COMPILE-FILE -- I'm not talking about the problem of separate file
compilations] LCL file-compilation arranges to preserve EQLness over the
data objects in a single compile-file.
At one time, some implementations didn't even preserve EQLness over
uninternd gensyms (over a single compile-file); but PCL dependended
so heavily on this working, that those implementations at least made
that case work.
-- JonL --
∂31-Dec-88 1036 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 31 Dec 88 10:33:19 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa03196; 31 Dec 88 18:18 GMT
Date: Sat, 31 Dec 88 18:20:56 GMT
Message-Id: <27761.8812311820@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Jon L White <@sail.stanford.edu:jonl@lucid.com>
In-Reply-To: Jon L White's message of Mon, 26 Dec 88 16:17:08 PST
Cc: sandra <@cs.utah.edu:sandra@defun>, KMP@scrc-stony-brook.arpa,
cl-compiler@sail.stanford.edu
> Ok, I see you point. The issue finally boils down to this:
>
> "Is the preservation of EQLness for quoted constants so important
> as to be the sole cause of yet another incompatibility between
> code compiled by COMPILE-FILE and code compiled by COMPILE?"
I'm not sure about "sole cause". There are other issues where
file compilation and EVAL/COMPILE might differ in their treatment
of constants, namely the questions of what types of objects can
appear in constants, what parts will be fasdumped, what happens
to circularities, and so forth. I think it comes down to whether
such constants will be treated as objects (like the objects that
are bound to variables) or not, which is also a kind of consistency
issue. Perhaps I'm wrong about the link between these issues. Kent
seems to want file compilation to be a special case in the other
issues but not to mind QUOTE copying. Still, they do seem linked to me.
Moreover, I'm not sure how far we'd have to extend the COMPILE-
FILE-like semantics in order to be consistent everywhere. For
example, there seems to be some doubt about what happens to gensyms.
Could it be that something like the following might return NIL?
(let ((a (gensym)))
(eql (funcall (compile nil `(lambda () ',a)))
(funcall (compile nil `(lambda () ',a)))))
Or even
(let ((a (gensym)))
(eval `(eql ',a ',a)))
> In short, I don't see the value of adding constraints that
> (1) invalidate much existing practice, and
How much of existing practice involves constant copying in interpreted
code?
-- Jeff
∂31-Dec-88 1151 CL-Compiler-mailer issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 31 Dec 88 11:50:52 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA26631; Sat, 31 Dec 88 12:49:50 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA04210; Sat, 31 Dec 88 12:49:47 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812311949.AA04210@defun.utah.edu>
Date: Sat, 31 Dec 88 12:49:45 MST
Subject: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 8
To: cl-compiler@sail.stanford.edu
This version incorporates changes suggested by Gray and Burke.
Forum: Compiler
Issue: COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
References: CLtL pages 66-70, 143
Category: CLARIFICATION
Edit history: V1, 07 Oct 1987 Sandra Loosemore
V2, 15 Oct 1987 Sandra Loosemore
V3, 15 Jan 1988 Sandra Loosemore
V4, 06 May 1988 Sandra Loosemore
V5, 20 May 1988 Sandra Loosemore
V6, 09 Jun 1988 Sandra Loosemore
V7, 16 Dec 1988 Sandra Loosemore
(Comments from Pitman, change DEFCONSTANT, etc.)
V8, 31 Dec 1988 Sandra Loosemore
(CLOS additions, etc.)
Problem Description:
Standard programming practices assume that, when calls to defining
macros such as DEFMACRO and DEFVAR are processed by COMPILE-FILE,
certain side-effects occur that affect how subsequent forms in the
file are compiled. However, these side-effects are not mentioned in
CLtL, except for a passing mention that macro definitions must be
``seen'' by the compiler before it can compile calls to those macros
correctly. In order to write portable programs, users must know
exactly which defining macros have compile-time side-effects and what
those side-effects are.
Inter-file compilation dependencies are distinct from, and not
addressed by, this issue.
Proposal: COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY
(1) Clarify that defining macros such as DEFMACRO or DEFVAR, appearing
within a file being processed by COMPILE-FILE, normally have
compile-time side effects which affect how subsequent forms in the
same file are compiled. A convenient model for explaining how these
side effects happen is that the defining macro expands into one or
more EVAL-WHEN forms, and that the calls which cause the compile-time
side effects to happen appear in the body of an (EVAL-WHEN (COMPILE)
...) form.
(2) The affected defining macros and their specific side effects are
as follows. In each case, it is identified what users must do to
ensure that their programs are conforming, and what compilers must do
in order to correctly process a conforming program.
DEFTYPE: Users must ensure that the body of a DEFTYPE form is
evaluable at compile time if the type is referenced in subsequent type
declarations. The compiler must ensure that the DEFTYPE'd type
specifier is recognized in subsequent type declarations. If the
expansion of a type specifier is not defined fully at compile time
(perhaps because it expands into an unknown type specifier or a
SATISFIES of a named function that isn't defined in the compile-time
environment), an implementation may ignore any references to this type
in declarations and/or signal a warning.
DEFMACRO, DEFINE-MODIFY-MACRO: The compiler must store macro
definitions at compile time, so that occurrences of the macro later on
in the file can be expanded correctly. Users must ensure that the
body of the macro is evaluable at compile time if it is referenced
within the file being compiled.
DEFUN: DEFUN is not required to perform any compile-time side effects.
In particular, DEFUN does not make the function definition available
at compile time. An implementation may choose to store information
about the function for the purposes of compile-time error-checking
(such as checking the number of arguments on calls), or to enable the
function to be expanded inline.
DEFVAR, DEFPARAMETER: The compiler must recognize that the variables
named by these forms have been proclaimed special. However, it must
not evaluate the initial value form or SETQ the variable at compile
time.
DEFCONSTANT: The compiler must recognize that the symbol names a
constant. An implementation may choose to evaluate the value-form at
compile time, load time, or both. Therefore users must ensure that
the value-form is evaluable at compile time (regardless of whether or
not references to the constant appear in the file) and that it always
evaluates to the same value.
DEFSETF, DEFINE-SETF-METHOD: The compiler must make SETF methods
available so that it may be used to expand calls to SETF later on in
the file. Users must ensure that the body of DEFINE-SETF-METHOD and
the complex form of DEFSETF are evaluable at compile time if the
corresponding place is referred to in a subsequent SETF in the same
file. The compiler must make these SETF methods available to
compile-time calls to GET-SETF-METHOD when its environment argument is
a value received as the &ENVIRONMENT parameter of a macro.
DEFSTRUCT: The compiler must make the structure type name recognized
as a valid type name in subsequent declarations (as for DEFTYPE) and
make the structure slot accessors known to SETF. In addition, the
compiler must save enough information about the structure type so that
further DEFSTRUCT definitions can :INCLUDE a structure type defined
earlier in the file being compiled. The functions which DEFSTRUCT
generates are not defined in the compile time environment, although
the compiler may save enough information about the functions to code
subsequent calls inline. The #S reader syntax may or may not be
available at compile time.
DEFINE-CONDITION: The rules are essentially the same as those for
DEFSTRUCT; the compiler must make the condition type recognizable as a
valid type name, and it must be possible to reference the condition
type as the parent-type of another condition type in a subsequent
DEFINE-CONDITION in the file being compiled.
DEFCLASS: The compiler must make the class name be recognized as a
valid type name in subsequent declarations (as for DEFTYPE) and be
recognized as a valid class name for DEFMETHOD parameter
specializers and for use as the :METACLASS option of a subsequent
DEFCLASS. The compiler must make the class definition available to
be returned by FIND-CLASS when its environment argument is a value
received as the &ENVIRONMENT parameter of a macro.
DEFGENERIC and DEFMETHOD: These are not required to perform any
compile-time side effects. In particular, the methods are not
installed for invocation during compilation. An implementation may
choose to store information about the generic function for the
purposes of compile-time error-checking (such as checking the number
of arguments on calls, or noting that a definition for the function
name has been seen).
DEFINE-METHOD-COMBINATION: The compiler is not required to perform
any compile-time side-effects.
DEFPACKAGE: All of the actions normally performed by this macro at load
time must also be performed at compile time.
(3) The compile-time side effects may cause information about the
definition to be stored differently than if the defining macro had
been processed in the "normal" way (either interpretively or by loading
the compiled file).
In particular, the information stored by the defining macros at
compile time may or may not be available to the interpreter (either
during or after compilation), or during subsequent calls to COMPILE or
COMPILE-FILE. For example, the following code is nonportable because
it assumes that the compiler stores the macro definition of FOO where
it is available to the interpreter:
(defmacro foo (x) `(car ,x))
(eval-when (eval compile load)
(print (foo '(a b c))))
A portable way to do the same thing would be to include the macro
definition inside the EVAL-WHEN:
(eval-when (eval compile load)
(defmacro foo (x) `(car ,x))
(print (foo '(a b c))))
Rationale:
The proposal generally reflects standard programming practices. The
primary purpose of the proposal is to make an explicit statement that
CL supports the behavior that most programmers expect and many
implementations already provide.
The primary point of controversy on this issue has been the treatment
of the initial value form by DEFCONSTANT, where there is considerable
variance between implementations. The effect of the current wording is
to legitimize all of the variants.
Current Practice:
Many (probably most) Common Lisp implementations, including VaxLisp
and Lucid Lisp, are already largely in conformance.
In VaxLisp, macro definitions that occur as a side effect of compiling
a DEFMACRO form are available to the compiler (even on subsequent
calls to COMPILE or COMPILE-FILE), but are not available to the
interpreter (even within the file being compiled).
By default, Kyoto Common Lisp evaluates *all* top level forms as they
are compiled, which is clearly in violation of the behavior specified
on p 69-70 of CLtL. There is a flag to disable the compile-time
evaluation, but then macros such as DEFMACRO, DEFVAR, etc. do not make
their definitions available at compile-time either.
Cost to implementors:
The intent of the proposal is specifically not to require the compiler
to have special knowledge about each of these macros. In
implementations whose compilers do not treat these macros as special
forms, it should be fairly straightforward to use EVAL-WHENs in their
expansions to obtain the desired compile-time side effects.
Cost to users:
Since CLtL does not specify whether and what compile-time side-effects
happen, any user code which relies on them is, strictly speaking,
nonportable. In practice, however, most programmers already expect
most of the behavior described in this proposal and will not find it
to be an incompatible change.
Benefits:
Adoption of the proposal will provide more definite guidelines on how
to write programs that will compile correctly under all CL
implementations.
Discussion:
Reaction to a preliminary version of this proposal on the common-lisp
mailing list was overwhelmingly positive. More than one person
responded with comments to the effect of "but doesn't CLtL already
*say* that somewhere?!?" Others have since expressed a more lukewarm
approval.
It has been suggested that this proposal should also include PROCLAIM.
However, since PROCLAIM is not a macro, its compile-time side effects
cannot be handled using the EVAL-WHEN mechanism. A separate proposal
seems more appropriate.
Item (3) allows for significant deviations between implementations.
While there is some sentiment to the effect that the compiler should
store definitions in a manner identical to that of the interpreter,
other people believe strongly that compiler side-effects should be
completely invisible to the interpreter. The author is of the opinion
that since this is a controversial issue, further attempts to restrict
this behavior should be considered as separate proposals.
It should be noted that user-written code-analysis programs must
generally treat these defining macros as special forms and perform
similar "compile-time" actions in order to correctly process
conforming programs.
-------
∂31-Dec-88 1224 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 31 Dec 88 12:24:24 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA27056; Sat, 31 Dec 88 13:23:24 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA04227; Sat, 31 Dec 88 13:23:21 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812312023.AA04227@defun.utah.edu>
Date: Sat, 31 Dec 88 13:23:20 MST
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
To: cl-compiler@sail.stanford.edu
This version tries to fix the wording problems mentioned by JonL.
Issue: DEFINING-MACROS-NON-TOP-LEVEL
References: CLtL p. 66-70, 143
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue COMPILER-LET-CONFUSION
Category: CLARIFICATION, ENHANCEMENT
Edit History: 6-May-88, V1 by Sandra Loosemore
9-Jun-88, V2 by Sandra Loosemore
12-Sep-88, V3 by Sandra Loosemore (fix garbled section 4)
21-Sep-88, V4 by Sandra Loosemore (clarify section 5)
16-Dec-88, V5 by Sandra Loosemore (major restructuring)
31-Dec-88, V6 by Sandra Loosemore (wording clarifications)
Problem Description:
CLtL leaves the interpretation of defining forms such as DEFMACRO and
DEFVAR that appear in other than top-level locations unclear.
On page 66, it is stated: "It is not illegal to use these forms at
other than top level, but whether it is meaningful to do so depends on
context. Compilers, for example, may not recognize these forms
properly in other than top-level contexts". At least one implementation
has interpreted this to mean that it is permissible to simply refuse
to compile defining macros that do not appear at top-level.
Proposal: DEFINING-MACROS-NON-TOP-LEVEL:ALLOW
(1) Remove the language from p. 66 of CLtL quoted above. Clarify that
while defining macros normally appear at top level, it is meaningful
to place them in non-top-level contexts and that the compiler must
handle them properly in all situations. However, the compile-time side
effects described in issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
only take place when the defining macros appear at top-level.
(2) Remove the language on p. 145 of CLtL, which states that macro
functions are always defined in the null lexical environment. Clarify
that all defining macros which create functional objects (including
DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
DEFSETF, as well as DEFUN) must ensure that those functions are
defined in the lexical environment in which the defining form is
evaluated.
(3) Define a ``top-level form'' as follows:
- Each form read by COMPILE-FILE from the input file is a top-level
form.
- Forms within the body of a top-level PROGN, EVAL-WHEN, or
COMPILER-LET are also top-level forms.
- The expansion of a top-level macro call is also a top-level form.
Top-level forms would be evaluated by the interpreter in a null
lexical environment, but that evaluation in a null lexical environment
does not necessarily imply that the form is top-level.
(4) Specify that top-level forms in a file being compiled are
guaranteed to be processed sequentially, including forms within the
body of a top-level PROGN, EVAL-WHEN, or COMPILER-LET. The order in
which non-top-level subforms of a top-level form are processed by the
compiler is explicitly left unspecified.
Rationale:
The notion of a ``top-level form'' is rather confused, since the term
is used in CLtL to refer both to a place where a form may appear (what
this proposal continues to call ``top-level''), and to instances of
forms which traditionally appear there (what this proposal calls
``defining macros'').
There has been a suggestion that the notion of a top-level form should
be extended to include forms in the body of a top-level LET, to allow
forms such as DEFUN to be meaningful there. However, we feel that a
cleaner solution is to remove the restrictions on the placement of
defining macros altogether.
The motivation for item (4) is that it allows compilers to perform
certain kinds of source-to-source transformations that change the
order of subforms.
Current Practice:
CLtL mentions only that forms within a top-level PROGN, and not
COMPILER-LET, are treated as top-level. However, COMPILER-LET is
also treated specially in implementations derived from the MIT Lisp
Machine (TI and Symbolics), as well as Lucid and Coral (but not
VaxLisp).
Cost to implementors:
Implementations that currently don't compile defining macros correctly
when they appear at non-top-level will have to be changed.
Cost to users:
None. This is a compatible extension.
Benefits:
The notion of defining macros as being somehow special when they
appear at top-level is removed. Allowing defining macros to appear
anywhere instead of restricting them to certain positions results in a
cleaner language design.
Discussion:
This proposal is consistent with the behavior specified in proposal
EVAL-WHEN-NON-TOP-LEVEL:IGNORE-COMPILE. In particular, if the compile
time side-effects for defining macros specified in proposal
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY are implemented using
EVAL-WHEN, the "right" compiler behavior for defining macros at
non-top-level will happen automatically.
Note that proposal COMPILER-LET-CONFUSION:ELIMINATE would remove
COMPILER-LET from the language entirely.
-------
∂31-Dec-88 1401 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 31 Dec 88 14:01:10 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA29146; Sat, 31 Dec 88 15:00:05 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA04267; Sat, 31 Dec 88 15:00:01 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8812312200.AA04267@defun.utah.edu>
Date: Sat, 31 Dec 88 14:59:59 MST
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: Jon L White <@sail.stanford.edu:jonl@lucid.com>,
sandra <sandra%defun@cs.utah.edu>, KMP@scrc-stony-brook.arpa,
cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Sat, 31 Dec 88 18:20:56 GMT
> Date: Sat, 31 Dec 88 18:20:56 GMT
> From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
>
> Could it be that something like the following might return NIL?
>
> (let ((a (gensym)))
> (eql (funcall (compile nil `(lambda () ',a)))
> (funcall (compile nil `(lambda () ',a)))))
>
> Or even
>
> (let ((a (gensym)))
> (eval `(eql ',a ',a)))
Rather than making an exception for gensyms, I'm inclined to believe
that *all* sharing of structures within an expression passed to EVAL,
a function passed to COMPILE, or the entire contents of a file
compiled with COMPILE-FILE ought to be preserved. I don't think it
would be unreasonable for your first example to return NIL, but I
think the second one ought to return true (regardless of whether the
value of A is a gensym or some other kind of object).
This really falls under issue CONSTANT-CIRCULAR-COMPILATION, although
both of the existing proposals on this issue say that sharing is not
required to be preserved (by analogy with *PRINT-CIRCLE*, which is
only required to detect circularity and not sharing). We now seem to
be moving away from the idea of COMPILE-FILE treating constants like
PRINT, however, so maybe it's time to consider this as an alternate
proposal.
-Sandra
-------
∂31-Dec-88 1943 CL-Compiler-mailer Issue COMPILER-LET-CONFUSION, v3
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 31 Dec 88 19:43:11 PST
Date: Sat 31 Dec 88 19:37:21-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue COMPILER-LET-CONFUSION, v3
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12458957456.23.IIM@ECLA.USC.EDU>
> Date: Mon, 26 Dec 88 23:21:38 PST
> From: Jon L White <jonl@lucid.com>
> Subject: issue COMPILER-LET-CONFUSION, V3
>> re: I've made a case that it [COMPILER-LET] expresses a useful high level
>> concept and that it can be coherently implemented. . . .
> And many of us don't buy that argument.
And some of us do. I freely admit that COMPILER-LET is rarely used, and
probably even more rarely used correctly because it isn't well documented. The
former is not, in itself, sufficient reason to remove it from the language. I
think I've personally used it maybe twice. In one of those instances,
replacing it with the proposed macrolet-style solution would involve sticking a
data structure into the expansion code as a quoted constant and depending on an
eq test to match it, which might not work in some implementations (re:
quote-may-copy). Since there are problems with the documentation, fix that.
Talk about problems like the possibility of differences between implementations
which do a prepass and those which don't. Cleanup and clarify. But don't
flush it unless you have clearly demonstrated that it is in fact useless (and
the fact that some reasonably well informed people don't agree that it is
useless means that such demonstration has not occured).
To turn your own question around, do you really feel that the next version of
CL will be "absolutely unacceptable" if it DOES have COMPILER-LET in it?
kab
-------
∂31-Dec-88 1946 CL-Compiler-mailer Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, v7
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 31 Dec 88 19:46:28 PST
Date: Sat 31 Dec 88 19:38:58-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, v7
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12458957749.23.IIM@ECLA.USC.EDU>
Date: Thu, 29 Dec 88 19:52:57 CST
From: David N Gray <Gray@DSG.csc.ti.com>
Subject: Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
> Shouldn't that last sentence say something like "... need not be defined
> ..."? Since the accessor functions commonly default to INLINE, they
> often will be defined at compile time.
No, the processing of the accessor functions should expand to code which does
something equivelent to
(progn
(proclaim '(inline <accessor>))
(defun <accessor> (structure)
<code to access the appropriate element of structure>
)
;; unless <accessor> is read-only
(defsetf <accessor> (structure) (value)
<expansion code to update the appropriate element of structure>
)
)
which does not make <accessor> defined at compile time (see DEFUN).
> DEFCLASS: ... and for use as the :METACLASS option of a subsequent
> DEFCLASS.
No, because doing so would require that the class be instantiable, so that you
can make instances whose class is the metaclass, for descrimination purposes.
That's what having it available as a metaclass is all about. I seem to
remember somewhere in the CLOS spec the caveat that a class had to be fully
defined before it could be used as a metaclass argument to defclass, presumably
for this reason.
> The compiler must make the class definition available to be returned by
> FIND-CLASS when its environment argument is a value received as the
> &ENVIRONMENT parameter of a macro.
This should perhaps be tightened up a bit. For example, the &environment
argument should have been generated by the same invocation of the compiler as
that which processed the defclass. For example, if I compile a file containing
a defclass of fred, don't load it, and compile a file with a compile-time call
to find-class on fred with the appropriate compile-time &environment argument,
it should not be assumed that this will return the thing that got generated by
the first file (though I don't want to say it must not, since some
implementations seem to have different ideas about the survival of compilation
side-effects over multiple files).
kab
-------
∂31-Dec-88 1951 CL-Compiler-mailer Issue DEFINING-MACROS-NON-TOP-LEVEL, v5
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 31 Dec 88 19:50:54 PST
Date: Sat 31 Dec 88 19:40:52-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue DEFINING-MACROS-NON-TOP-LEVEL, v5
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12458958097.23.IIM@ECLA.USC.EDU>
Regarding the definition of top-level, a case can be made for macrolet not
pushing you from top-level to non-top-level. The argument is that you can take
a macrolet form, process the body to the extent of macroexpanding everything,
throw away the macrolet, and then process the body as a top-level progn. When
we (at IIM) worked out what our compiler's notion of top-level was going to be,
my boss argued us into implementing it this way. In general it turns out to be
a useful way to do things.
kab
-------
∂31-Dec-88 1953 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 31 Dec 88 19:52:53 PST
Date: Sat 31 Dec 88 19:42:42-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12458958430.23.IIM@ECLA.USC.EDU>
> Date: Wed, 21 Dec 88 20:21:57 PST
> From: Jon L White <jonl@lucid.com>
> Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 2
> Since we are tending towards flushing COMPILER-LET, then I favor restricting
> the COMPILE situation to "toplevel" forms.
I'm not sure what the proposed flushing of COMPILER-LET has to do with this.
And what do you mean by "restricting" the COMPILE situation to top-level forms?
You can't say that the COMPILE situation is flat-out illegal except at
top-level if you want both DEFINING-FORMS-NON-TOP-LEVEL and the discussion of
using (EVAL-WHEN (COMPILE) ...) to perform the compile-time magic of defining
macros, as described in COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS.
I agree wholeheartedly that we need to tighten up the definition of
"top-level". I have a strawman proposal roughed out mentally, but haven't had
time to actually write it down. Maybe this weekend, since I seem to be in
X3J13 mode.
> "When an EVAL-WHEN form is processed by the compiler:"
> lists two alternatives in a way that might imply they are mutually
> exclusive:
> (1) If the situation COMPILE is specified:
> ...
> (2) If the situation LOAD is specified, ...
> One needs to cover the case when both COMPILE and LOAD are specified.
That's supposed to be a two step process. First the compiler does the stuff in
(1). Then it does the stuff in (2). The supplied macro definition for
eval-when makes this clear, but is placed far away.
> In addition, does the compiler act differently on situation (EVAL) than it
> does on situation (LOAD)? How about (EVAL LOAD)?
The compiler completely ignores the EVAL situation. It is only interested in
whether the COMPILE situation is present (if at top-level), and if the LOAD
situation is present (always). I seem to remember that Spice Lisp had the
compiler processing non-top-level EVAL situations in the way the proposal says
to handle LOAD, so Lucid may have inherited this (assuming I'm correctly
informed about the ancestry of some of Lucid's work). Early on we decided to
change away from Spice to our current interpretation (which is essentially what
the proposal consists of).
kab
-------
∂31-Dec-88 1956 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 31 Dec 88 19:56:24 PST
Date: Sat 31 Dec 88 19:44:13-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue COMPILER-DIAGNOSTICS, v7
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12458958705.23.IIM@ECLA.USC.EDU>
> Date: Fri, 23 Dec 88 17:50 EST
> From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> Subject: issue COMPILER-DIAGNOSTICS, version 7
> I would not use terms like NOTICE, ALERT, etc. because I think people
> will not like our locking down so many highly generic words. Furthermore,
> I think you'd have a hard time making a serious case that there was a
> need for that particular number of gradations without some experience to
> back it up. In my opinion, it would be better at this point to gain
> some experience in real implementations and then to suggest things like
> this on the next standardization cycle.
>
> Even so, I would expect that the most likely to be adopted types would
> be subtypes of WARNING, not disjoint types. eg, STYLE-WARNING. Making
> them subtypes of WARNING means you can use WARN without introducing a
> new primitive. It means you can use MUFFLE-WARNING without introducing
> other MUFFLE-xxx things. Simpler. Little or no lost functionality.
For the most part I agree with Kent. However, I think there is a difference
between things like style warnings and progress type messages of the form
Compiling function FRED.
It seems reasonable to give the user a mechanism for controling that kind of
output too, but I don't really think of such messages as warnings. NOTICE
seems like a nice, simple thing to use to say that something is happening but
you can ignore it if you like, but maybe the name implies more priority than is
intended. Maybe some other name?
kab
-------
∂31-Dec-88 1959 CL-Compiler-mailer environment arguments and compiler contexts and ...
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 31 Dec 88 19:58:33 PST
Date: Sat 31 Dec 88 19:45:54-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: environment arguments and compiler contexts and ...
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12458959011.23.IIM@ECLA.USC.EDU>
To: cl-compiler
Re: environment arguments and compiler contexts and ...
This is kind of a "toss out some problems and see if anybody has any ideas"
kind of message. It's probably going to be a bit stream-of-consciousness.
PROBLEM 1
While in general I think the change that CLOS implicitly made, requiring a
distinguishable &environment argument for the compiler, and basing certain
lookups based on it, there are some problems with this in actual use. For
example, if I want to implement a DEFGENERIC macro, the obvious ways to do so
are
(defmacro defgeneric (spec lambda-list &rest options &environment env)
(when (and (compiler-environment-p env)
(compiler-at-top-level-p env))
(apply #'ensure-generic-function
spec
lambda-list
:environment env
(parse-defgeneric-options options)))
`(apply #'ensure-generic-function
',spec
',lambda-list
(parse-defgeneric-options ',options)))
or
(defmacro defgeneric (spec lambda-list &rest options &environment env)
`(progn
(eval-when (compile)
(apply #'ensure-generic-function
',spec
',lambda-list
:environment ',env
(parse-defgeneric-options ',options)))
(eval-when (load eval)
(apply #'ensure-generic-function
',spec
',lambda-list
(parse-defgeneric-options ',options)))))
Now both of these definitions have some problems.
The first macro has at least the following problems:
(1) Its expander function causes side effects, which is just generally
considered to be not a good thing, though you can often get away with it.
(2) The compiler-environment-p predicate is necessary to prevent improperly
clobbering the running system, since we are assuming that
ensure-generic-function will "do the right thing" when the environment is from
the compiler. But this means that this macro (and any like it) can't just call
the appropriate side-effecting function. They have to themselves distinguish
environment types, which means that this predicate needs a more official status
than it currently has.
(3) A program analyzer of the type Sandra mentioned sometime back (reads a
file, doing macroexpansions and decorating/transforming the results, then
writes out the resulting forms using print) currently doesn't have a way to
generate a distinguishable compiler environment object, so it has to
explicitely know about every such macro and have a way to perform the
compile-time magic itself in such a way that the rest of the system will
understand. This is clearly bogus.
The second macro puts the environment argument into the expansion form as a
hard-coded constant. There are lots of reasons this might lose. Just to name
a few that I can think of off the top of my head
(1) If there are EQ dependencies involved in manipulation of environments,
Issue QUOTE-MAY-COPY makes this bad.
(2) This may lose in an implementation which stack-conses environments. The
PCL code walker talks about this problem and goes to some trouble to avoid
being bitten by it.
(3) Sandra's program analyzer example is going to try to print the environment
to a file which will later be read back in in a meaningful way. Good luck.
PROBLEM 2
Here's another problem exercised by Sandra's program analyzer example (gosh,
this thing sure seems to be a useful tool for thought experiments). The way
she described it, it would do many of the same actions as a compiler.
Specifically, it would perform the same action a compiler would when
encountering and eval-when form specifying a compile situation, eval'ing the
body forms when appropriate. Unfortunately, in at least one implementation
(IIM Common Lisp), this is almost certain to lose. The reason is that what we
put in these (eval-when (compile) ...) forms is often code which assumes that
it is really being called by the compiler. The compiler sets up certain
context information, without which the code in the eval-when's will at best
cause immediate errors, or worse, might just silently appear to have worked
when in fact they have done something fairly unpredictable.
A solution to this might be something like a WITH-COMPILATION wrapper macro,
which will do things like setting up any necessary contextual information, and
provide you with an initial compiler-type macro environment. Of course, to be
useful, accessors and update functions on the environment object are still
needed. There is already an issue that addresses that,
SYNTACTIC-ENVIRONMENT-ACCESS.
kab
-------
∂01-Jan-89 0258 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 1 Jan 89 02:58:42 PST
Date: Sat 31 Dec 88 19:34:35-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12458956952.23.IIM@ECLA.USC.EDU>
The issue SYNTACTIC-ENVIRONMENT-ACCESS mentions a proposal before cleanup to
add optional environment arguments to MACRO-FUNCTION and GET-SETF-METHOD. Does
anyone happen to know the status of that proposal, and did it mention any other
functions that needed environment arguments? BTW, I'd like to try to avoid
letting SYNTACTIC-ENVIRONMENT-ACCESS die of neglect. I think something like
what it proposes is pretty important. I believe Sandra said (in one of her
status messages) that Eric Benson was going to do a new writeup. Sandra, have
you heard anything from him? Do you have an address for him so I can poke
him? Is he an X3J13 member?
kab
-------
∂01-Jan-89 0510 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 1 Jan 89 05:10:05 PST
Date: Sat 31 Dec 88 19:39:52-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue COMPILER-DIAGNOSTICS, v7
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12458957912.23.IIM@ECLA.USC.EDU>
> Date: Tue, 20 Dec 88 15:22:36 EST
> From: Dan L. Pierson <pierson@mist.encore.com>
> Subject: Re: issue COMPILER-DIAGNOSTICS, version 7
> I agree. I lumped ALERT and NOTICE together to keep them from causing
> BREAKs.
This doesn't seem necessary, with the depreciation of *break-on-warnings* in
the current condition system, being replaced by *break-on-signals*
kab
-------
∂01-Jan-89 1022 CL-Compiler-mailer Re: environment arguments and compiler contexts and ...
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 1 Jan 89 10:21:26 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA16295; Sun, 1 Jan 89 11:20:20 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA04701; Sun, 1 Jan 89 11:20:15 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901011820.AA04701@defun.utah.edu>
Date: Sun, 1 Jan 89 11:20:14 MST
Subject: Re: environment arguments and compiler contexts and ...
To: Kim A. Barrett <IIM@ECLA.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett <IIM@ECLA.USC.EDU>, Sat 31 Dec 88 19:45:54-PST
This message raises some interesting points.
I've also been a bit wary about how CLOS seems to assume things about
environments, although there's already a problem with the language as
described in CLtL because of MACROLET and MACROEXPAND. To me it seems
like that if we're going to place additional requirements about what
must be stored in environments, we must also tighten up the notion of
what an environment object is. Is it supposed to be a distinct type?
Are they guaranteed to be printable and compilable? How do you add
things to an environment or find out what's in it? I'm not sure that
we have enough practical experience yet to try to standardize the use
of environments as something like locales in T.
The writeup for issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS already
notes that portable program-analyzing programs must generally treat
defining macros as special forms. If these defining macros are
allowed to store the compile-time definitions in somewhere other than
the normal place (that is, in the environment or some data structure
set up by the compiler, rather than where the interpreter would put
the definition), user program analyzers have no way to access this
information. Also, it's possible that the compiler might be treating
the defining macros as special forms itself and the macro expansions
might not do any special compile-time magic.
I'd have to disagree about that requiring program analyzers to know
about defining macros being "bogus", however. I suspect that an
"industrial strength" program analyzer would want to have special
knowledge about *most* built-in Common Lisp macros, rather than just
expanding them blindly. The reason for this is that many compilers
treat them as special forms, and while the macro expansions are
correct, they are often much less efficient. (Some of the multiple
value macros come to mind.)
-Sandra
-------
∂01-Jan-89 1243 CL-Compiler-mailer Re: environment arguments and compiler contexts and ...
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 1 Jan 89 12:42:26 PST
Date: Sun 1 Jan 89 12:28:04-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Re: environment arguments and compiler contexts and ...
To: sandra%defun@CS.UTAH.EDU
cc: cl-compiler@SAIL.STANFORD.EDU, IIM@ECLA.USC.EDU
In-Reply-To: <8901011820.AA04701@defun.utah.edu>
Message-ID: <12459141451.23.IIM@ECLA.USC.EDU>
> From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Sun, 1 Jan 89 11:20:14 MST
> Subject: Re: environment arguments and compiler contexts and ...
> To me it seems like that if we're going to place additional requirements
> about what must be stored in environments, we must also tighten up the
> notion of what an environment object is. ... I'm not sure that we have
> enough practical experience yet to try to standardize the use of
> environments as something like locales in T.
Yet if we're going to admit the possibility of portable program analyzers, and
want to support them in any reasonable way, I think we are forced to consider
standardizing environments in some fashion (see below). This is why I think
the SYNTACTIC-ENVIRONMENT-ACCESS issue is so important.
> If these defining macros are allowed to store the compile-time definitions
> in somewhere other than the normal place ... user program analyzers have no
> way to access this information. ... I'd have to disagree about that
> requiring program analyzers to know about defining macros being "bogus",
> however.
The reason I say it's bogus is that (without SYNTACTIC-ENVIRONMENT-ACCESS or
some such thing), the user written program has no way to put the compile-time
definitions in a place where the implementation-supplied functions will find
them, other than by side-effecting the running system. For example, if my
program analyzer encounters a defmacro, how am I supposed to write code to
tell macro-function and macroexpand where to find the definition I am going
to record. Writing my own varient versions of these won't work unless I
actually clobber the implementation's version with mine, since there will be
code that will call the built in function because it never heard about my
analyzer (and shouldn't have needed to). And even that horrible kludge
doesn't really work, since there could reasonably be multiple different
program analyzers, all with their own ideas about where to look things up,
(I can't go on, its too terrible to even contemplate).
kab
-------
∂01-Jan-89 2050 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 1 Jan 89 20:50:48 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA02539g; Sun, 1 Jan 89 20:47:10 PST
Received: by bhopal id AA21352g; Sun, 1 Jan 89 20:49:23 PST
Date: Sun, 1 Jan 89 20:49:23 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901020449.AA21352@bhopal>
To: IIM@ECLA.USC.EDU
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett's message of Sat 31 Dec 88 19:42:42-PST <12458958430.23.IIM@ECLA.USC.EDU>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
re: I seem to remember that Spice Lisp had the compiler
processing non-top-level EVAL situations in the way the proposal says to
handle LOAD, so Lucid may have inherited this (assuming I'm correctly
informed about the ancestry of some of Lucid's work).
You are not correctly informed. Lucid's compiler is a spiritual descendent
of the S1/NIL compiler. I am also not aware of any part of Lucid product
that is a direct descendent of Spice code (although some of the developers
looked at the Spice sources back in the fall of 1984).
As to comments about the rest of your message: you appear to be
explicating your code example, and how such might apply to may questions.
But my questions were directed towards the specification (which, I HOPE,
is in English). Sandra's recent revision seems to have handled them
adequately.
-- JonL --
∂01-Jan-89 2055 CL-Compiler-mailer Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 1 Jan 89 20:55:50 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa01152; 1 Jan 89 23:55 EST
Received: from draper.com by RELAY.CS.NET id aa18712; 1 Jan 89 23:45 EST
Date: Sun, 1 Jan 89 22:53 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Re: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 7
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER,SEB1525
Of course - unless eval-when (compile) is a default for the way that
(defstruct foo bar baz) is compiled, a call to foo-bar as part of a
macro expansion will fail. I guess I misread the original message -
missed the point questioning whether declaring a function INLINE necessarily
means that the function definition is visible to the compiler for evaluation.
If that is what was intended, it wasn't clear to me.
∂02-Jan-89 0015 CL-Compiler-mailer Issue COMPILER-LET-CONFUSION, v3
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 2 Jan 89 00:15:20 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA02617g; Mon, 2 Jan 89 00:11:42 PST
Received: by bhopal id AA21841g; Mon, 2 Jan 89 00:13:53 PST
Date: Mon, 2 Jan 89 00:13:53 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901020813.AA21841@bhopal>
To: IIM@ECLA.USC.EDU
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett's message of Sat 31 Dec 88 19:37:21-PST <12458957456.23.IIM@ECLA.USC.EDU>
Subject: Issue COMPILER-LET-CONFUSION, v3
re: But don't flush it [COMPILER-LET]
unless you have clearly demonstrated that it is in fact useless (and
the fact that some reasonably well informed people don't agree that it
is useless means that such demonstration has not occured).
I don't accept this as an adequate criterion. If in fact a facility is
poorly documented because it is poorly conceived, and if it generates
immense confusion in the user community, and if there are alternate ways
of accomplishing the same effect, and if it is seldom used because of
the aforementioned shortcomings, then it ought to be flushed. [#, is one
such facility even though there is currently no alternative; we hope to
replace it with the much better and well-thought-out LOAD-TIME-VALUE]
COMPILER-LET has abundantly been demonstrated to generate immense
confusion in the user community. And the fact that its defenders have
*no* convincing examples where this construct is either critical
or suprememly better than the alternatives means it is simply a
confusing hack. It's rare uses hardly justify its enormous drawback.
"Reasonably well informed people" have upon ocasion been know to
succumb to a hack.
-- JonL --
∂02-Jan-89 0222 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 2 Jan 89 02:22:24 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA02628g; Mon, 2 Jan 89 02:18:46 PST
Received: by bhopal id AA22058g; Mon, 2 Jan 89 02:20:55 PST
Date: Mon, 2 Jan 89 02:20:55 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901021020.AA22058@bhopal>
To: IIM@ECLA.USC.EDU
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett's message of Sat 31 Dec 88 19:33:20-PST <12458956724.23.IIM@ECLA.USC.EDU>
Subject: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Eric Benson reads the CL-Cleanup mails, and ocasionally participates
in its discussions. His address is eb@lucid.com, but he's on vacation
right now.
I think one can assume that MACRO-FUNCTION and GET-SETF-METHOD will
neeed &environment arguments. The issue for GET-SETF-METHOD was
"passed" in June 1987.
I fear that we have let MACRO-FUNCTION drop on the floor. Larry's
"Issue Status" for the Ft. Collins meeting (Nov 1987) says that
it "need[s a] volunteer" to write it up. I don't recall seeing a
subsequent proposal. It ought to be trivial.
For the record, Lucid's implementation of MACRO-FUNCTION has an
optional second argument for the &environment.
-- JonL --
∂02-Jan-89 1328 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Jan 89 13:28:15 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 514035; 2 Jan 89 16:26:46 EST
Date: Mon, 2 Jan 89 16:26 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-OBJECTS (Version 1)
To: CL-Cleanup@sail.stanford.edu
cc: Common-Lisp-Object-System@Sail.Stanford.edu, CL-Compiler@Sail.Stanford.edu
In-Reply-To: <19881229175913.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890102212611.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
This was discussed on the clos and compiler lists. I thought it would
be a good idea to write it up for discussion and give the cleanup group
a look at it. I think it's something that fell in the cracks between
these three subcommittees.
Issue: LOAD-OBJECTS
References: none
Related issues: none
Category: ADDITION
Edit history: Version 1, 2-Jan-89, by Moon (for discussion)
Problem description:
Common Lisp doesn't provide any way to use an object of a user-defined
type (defined with DEFCLASS or DEFSTRUCT) as a constant in a program
compiled with COMPILE-FILE. The problem is that LOAD has to be able
to "reconstruct" an equivalent object when the compiled-code file is
loaded, but the programmer has no way to tell LOAD how to do that.
Proposal (LOAD-OBJECTS:MAKE-LOAD-FORM):
Define a new generic function named MAKE-LOAD-FORM, which takes one
argument and returns one value. The value is a form which, when
evaluated at some later time, should return an object that is
equivalent to the argument. The exact meaning of "equivalent"
depends on the type of object and is up to the programmer who
defines a method for MAKE-LOAD-FORM.
Define that COMPILE-FILE calls MAKE-LOAD-FORM on any object that
appears in a constant and has STANDARD-CLASS or STRUCTURE-CLASS as a
metaclass. Define that COMPILE-FILE will only call MAKE-LOAD-FORM
once for any given object (compared with EQ) within a single file.
It is unspecified whether LOAD calls EVAL on the form or does some
other operation that has an equivalent effect.
Define that an instance of a class defined with DEFCLASS without any
direct superclasses, or defined with DEFSTRUCT without the :TYPE or
:INCLUDE options, does not inherit any method for MAKE-LOAD-FORM other
than possibly a method that only signals an error.
Example:
(defclass my-class ()
((a :initarg :a :reader my-a)
(b :initarg :b :reader my-b)
(c :accessor my-c)))
(defmethod shared-initialize ((self my-class) ignore &rest ignore)
(unless (slot-boundp self 'c)
(setf (my-c self) (some-computation (my-a self) (my-b self)))))
(defmethod make-load-form ((self my-class))
`(make-instance ',(class-name (class-of self))
:a ',(my-a self) :b ',(my-b self)))
In this example, an equivalent instance of my-class is reconstructed
by using the values of two of its slots. The value of the third slot
is derived from those two values.
(defclass my-frob ()
((name :initarg :name :reader my-name)))
(defmethod make-load-form ((self my-frob))
`(find-my-frob ',(my-name self) :if-does-not-exist :create))
In this example, instances of my-frob are "interned" in some way.
An equivalent instance is reconstructed by using the value of the
name slot as a key for searching existing objects. In this case
the programmer has chosen to create a new object if no existing
object is found; alternatively she could have chosen to signal an
error in that case.
Rationale:
Only the programmer who designed a class can know the correct
way to reconstruct objects of that class at load time, therefore
the reconstruction should be controlled by a generic function.
Using EVAL as the interface for telling LOAD what to do provides
full generality.
A default method, such as one that makes an object whose class has the
same name and whose slots have equivalent contents, is not supplied
because this is inappropriate for many objects and because it is easy
to write for those objects where it is appropriate.
MAKE-LOAD-FORM has a natural resemblance to PRINT-OBJECT.
Current practice:
Symbolics Flavors has something like this, but under a different name.
The name Symbolics uses is not suitable for standardization.
JonL reports that Lucid is getting more and more requests for this.
Cost to Implementors:
This seems like only a few one-line changes in the compiled-code
file writer and reader.
Cost to Users:
None.
Cost of non-adoption:
Serious impairment of the ability to use extended-type objects. Each
implementation will probably make up its own version of this as an
extension.
Performance impact:
None.
Benefits:
See Cost of non-adoption.
Esthetics:
No significant positive or negative impact.
Discussion:
It would be possible to define an additional level of protocol that
allows multiple classes to contribute to the reconstruction of an
object, combining initialization arguments contributed by each class.
Since a user can easily define that in terms of MAKE-LOAD-FORM without
modifying the Lisp system, it is not being proposed now.
Any type that has a read syntax is likely to appear as a quoted
constant or inside a quoted constant. Pathnames are one example, user
programs often define others. Also many implementations provide a way
to create a compiled-code file full of data (rather than compiled Lisp
programs), and such data probably include extended-type objects.
Moon supports this.
∂02-Jan-89 1912 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 2 Jan 89 19:12:15 PST
Date: Mon 2 Jan 89 17:28:34-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: JonL@LUCID.COM
cc: cl-compiler@SAIL.STANFORD.EDU, iim@ECLA.USC.EDU
Message-ID: <12459458298.4.IIM@ECLA.USC.EDU>
> Date: Sun, 1 Jan 89 20:49:23 PST
> From: Jon L White <jonl@lucid.com>
> Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
> > ... so Lucid may have inherited this (assuming I'm correctly informed
> > about the ancestry of some of Lucid's work).
> You are not correctly informed.
I was responding to part of what I thought you were asking. Since my
interpretation of your line of questioning was partly based in incorrect
information, I gave you an answer which didn't have much to do with anything.
Sorry about that.
Yes, Sandra's recent revision seems to clear things up considerably.
Now the real question is, is this really what we want to do? I certainly
didn't expect my "strawman" proposal to get through unscathed. My boss keeps
muttering that there's got to be a better way. Back when we (IIM) designed our
present implementation of EVAL-WHEN, we tossed around some ideas for
alternative mechanisms, but never got around to doing anything about them. And
now, of course, nobody here really remembers any of those ideas (though we're
all sure they were beautifully clean and elegent :-).
kab
-------
∂02-Jan-89 2053 CL-Compiler-mailer issue COMPILE-ARGUMENT-PROBLEMS
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Jan 89 20:52:45 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 514147; Mon 2-Jan-89 23:50:13 EST
Date: Mon, 2 Jan 89 23:49 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILE-ARGUMENT-PROBLEMS
To: sandra%defun@CS.Utah.EDU
cc: CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <8808081611.AA01749@defun.utah.edu>
Message-ID: <890102234933.7.KMP@BOBOLINK.SCRC.Symbolics.COM>
I took the liberty of writing a version of this based around the
comments I made following your last proposal. The Proposal part
is very different, but I think it is "doable" in most implementations.
Personally, I think this proposal will be a lot more useful in
practice. I hope others will agree.
-kmp
------
Issue: COMPILE-ARGUMENT-PROBLEMS
References: CLtL p. 438-439
Issue FUNCTION-TYPE
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CLARIFICATION, CHANGE
Edit History: 08-Aug-88, Version 1 by Sandra Loosemore
02-Jan-89, Version 2 by Pitman
Problem Description:
The description of what arguments can legitimately be passed to the
function COMPILE in CLtL is too vague. There are two specific
problems:
(1) Acceptance of the FUNCTION-TYPE proposal makes it nonsensical to
speak of a lambda-expression being an interpreted function (it is not)
or to require a symbol to have a lambda-expression as its definition
(the SYMBOL-FUNCTION must be a true FUNCTION object).
(2) Many implementations cannot correctly compile functions that are
defined interpretively in a non-null lexical environment, because the
compiler and interpreter use different representations for closures.
Although this problem arose in conjunction with the
DEFINING-MACROS-NON-TOP-LEVEL proposal, the situation can also arise
if SETF is used to store a lexical closure in the SYMBOL-FUNCTION of
the symbol.
(3) Compiled-only implementations are caught in a bind because the
one-argument case as described in CLtL can never not signal an error:
the contents of the function cell are always compiled.
Proposal (COMPILE-ARGUMENT-PROBLEMS:HARMLESS):
Change the description of COMPILE to say that the function to be
compiled may be either a lambda expression (as permitted by CLtL)
or a function (as described by the FUNCTION-TYPE proposal). If the
definition is a lambda expression, it is coerced to a function.
If the definition to be compiled is already compiled, the implementation
is permitted to treat the compilation step as an identity. In any case,
the implementation must not signal an error.
If the definition to be compiled is a function which was enclosed in
a non-null lexical environment and the compiler cannot compile the
function, the compiler is permitted to treat the compilation step
as an identity.
If the definition to be compiled is a macro or special form definition,
the compiler is permitted to treat the compilation step as an identity.
If an implementation is interpreted-only, the compiler is permitted
to treat the compilation step as an identity.
The intent is that the COMPILE function should signal an error only if
it receives an argument which is not the name or definition of a valid
function, macro, or special form.
The intent is that COMPILE should be a permissible way to attempt to
`speed up' any operator definition. Implementations are encouraged to
implementation useful facilities toward this end. However, if a
definition cannot be `sped up' for some reason (for example, the
definition is already compiled, or there is some limitation of the
compiler), the original definition should be used where feasible.
For example, it should in general be permissible to do:
(DO-SYMBOLS (SYMBOL package)
(IF (FBOUNDP SYMBOL) (COMPILE SYMBOL)))
to `speed up' the functions in some PACKAGE.
Rationale:
This provides a consistent interpretation of COMPILE which is useful
in portable code in interpreted-only, compiled-only, or hybrid
interpreted/compiled implementations.
The definition is flexible enough to permit implementations to skip
compilation in situations where the implementor deems it unreasonable.
Current Practice:
Implementations that do not allow sharing of lexical environments
between compiled and interpreted functions include VaxLisp, Allegro
CL, and Lucid.
Lucid and Symbolics already accept an interpreted function object
as the "definition" argument to COMPILE.
Symbolics Genera signals an error if you try to compile an
already-compiled function.
Cost to implementors:
Very small. This is really just a change in the COMPILE function
interface, not in the compiler itself.
Cost to users:
None. Some cases which used to signal an error will no longer signal
an error.
Benefits:
This definition makes for a more useful interpretation of the
one-argument case of COMPILE in compiled-only implementations.
Uses of COMPILE will be more portable.
Cost of Non-Adoption:
The definition of COMPILE will be a real mess.
Discussion:
Pitman supports this proposal.
∂02-Jan-89 2058 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 2 Jan 89 20:58:37 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA05679; Mon, 2 Jan 89 21:56:52 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05311; Mon, 2 Jan 89 21:56:43 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901030456.AA05311@defun.utah.edu>
Date: Mon, 2 Jan 89 21:56:42 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: Kim A. Barrett <IIM@ECLA.USC.EDU>
Cc: JonL@LUCID.COM, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett <IIM@ECLA.USC.EDU>, Mon 2 Jan 89 17:28:34-PST
> Date: Mon 2 Jan 89 17:28:34-PST
> From: Kim A. Barrett <IIM@ECLA.USC.EDU>
>
> Now the real question is, is this really what we want to do? I certainly
> didn't expect my "strawman" proposal to get through unscathed.
Well, I'm glad that the writeup is at least making sense now.
I personally don't have particularly strong feelings on this issue. I
think that the most questionable aspect of the current proposal is
that it can cause multiple evaluations if you have nested EVAL-WHENs,
for example
(eval-when (eval compile load)
(eval-when (eval compile load)
(this-fn-gets-called-twice-at-compile-time)))
I can think of some rather contrived examples where the second
compile-time evaluation in the inner EVAL-WHEN might get screwed up by
side-effects of subsequent forms in the outer EVAL-WHEN (such as
SETQ'ing a global variable it depends on).
One possible "fix" would be to specify that EVAL-WHEN doesn't pass
"top-level-ness" on to its body if both the COMPILE and LOAD
situations are specified (thus suppressing the second evaluation of
the nested EVAL-WHENs), but I'm not convinced that wouldn't cause some
additional problems of its own.
Anybody else have thoughts on this?
-Sandra
-------
∂02-Jan-89 2104 CL-Compiler-mailer Re: issue COMPILE-ARGUMENT-PROBLEMS
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 2 Jan 89 21:04:13 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA05732; Mon, 2 Jan 89 22:02:58 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05326; Mon, 2 Jan 89 22:02:46 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901030502.AA05326@defun.utah.edu>
Date: Mon, 2 Jan 89 22:02:45 MST
Subject: Re: issue COMPILE-ARGUMENT-PROBLEMS
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Mon, 2 Jan 89 23:49 EST
I'm confused about what you want to do here. This issue was passed
(with an amendment) at the October meeting. Do you want to reopen
this issue?
Here is the text of the proposal that was voted on, as amended:
Issue: COMPILE-ARGUMENT-PROBLEMS
References: CLtL p. 438-439
Issue FUNCTION-TYPE
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CLARIFICATION, CHANGE
Edit History: V1, Sandra Loosemore (8 Aug 1988)
V2, Sandra Loosemore (21 Sep 1988)
V3, Sandra Loosemore (14 Oct 1988)
Problem Description:
The description of what arguments can legitimately be passed to the
function COMPILE in CLtL is too vague. There are two specific
problems:
(1) Acceptance of the FUNCTION-TYPE proposal makes it nonsensical to
speak of a lambda-expression being an interpreted function (it is not)
or to require a symbol to have a lambda-expression as its definition
(the SYMBOL-FUNCTION must be a true FUNCTION object).
(2) Many implementations cannot correctly compile functions that are
defined interpretively in a non-null lexical environment, because the
compiler and interpreter use different representations for closures.
Although this problem arose in conjunction with the
DEFINING-MACROS-NON-TOP-LEVEL proposal, the situation can also arise
if SETF is used to store a lexical closure in the SYMBOL-FUNCTION of
the symbol.
Proposal COMPILE-ARGUMENT-PROBLEMS:CLARIFY:
If the optional "definition" argument to COMPILE is supplied, it may
be either a lambda expression (which is coerced to a function) or a
function to be compiled. Otherwise, the SYMBOL-FUNCTION of the symbol
is extracted and compiled. It is an error if the function to be
compiled was defined interpretively in a non-null lexical environment.
The consequences of calling COMPILE on a function that is already compiled
are unspecified.
Clarify that a symbol which names a macro may also be passed to COMPILE.
(Both macros and functions may be compiled.)
Rationale:
Saying "it is an error" to try to compile the wrong kind of function
allows implementations that can compile functions defined in a
non-null lexical environment to go ahead and do so.
Current Practice:
Implementations that do not allow sharing of lexical environments
between compiled and interpreted functions include VaxLisp, Allegro
CL, and Lucid. Lucid and VaxLisp already accept an interpreted function
object as the "definition" argument to COMPILE.
Cost to implementors:
Most of the changes required for this proposal are already necessary
to correctly implement the FUNCTION-TYPE proposal. The primary addition
is that COMPILE must be extended to accept a FUNCTION object as well
as a lambda expression as the "definition" argument.
Cost to users:
None. This is an upward-compatible change, since a lambda expression
can still be passed as an argument to COMPILE. Also, since most
existing implementations refuse to compile a function with a non-empty
lexical environment, user code which depends on being able to do this
is already nonportable.
Benefits:
An area of ambiguity in the language is resolved.
Discussion:
Acceptable behavior for COMPILE when it receives a function that is
already compiled might include doing nothing; performing more compilation
(if the function is only partially compiled); or retrieving the source
code and recompiling it. It is not acceptable to "crash and burn" or
signal an error.
-------
∂02-Jan-89 2119 CL-Compiler-mailer Re: issue COMPILE-ARGUMENT-PROBLEMS
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Jan 89 21:19:26 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 514164; Tue 3-Jan-89 00:17:22 EST
Date: Tue, 3 Jan 89 00:14 EST
From: KMP@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: issue COMPILE-ARGUMENT-PROBLEMS
To: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.STANFORD.EDU
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8901030502.AA05326@defun.utah.edu>
Message-ID: <890103001645.0.KMP@BOBOLINK.SCRC.Symbolics.COM>
Supersedes: <890103001457.8.KMP@BOBOLINK.SCRC.Symbolics.COM>,
<890103001640.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Redirected-Date: Tue, 3 Jan 89 00:16 EST
Redirected-by: KMP@STONY-BROOK.SCRC.Symbolics.COM
[This message has been redirected:
Sorry. I sent that message to the wrong list.
CL-Cleanup@SAIL.Stanford.EDU has been removed;
CL-Compiler@SAIL.Stanford.EDU has been added.]
I had forgotten the issue was voted on.
I do, however, think there are substantial benefits to be gained from my
new proposal over the other one. I think any definition of COMPILE which
permits it to err at random (which is pretty much how I feel about all
these "is an error" situations) severely cripples the usefulness of COMPILE
in really portable code. Signalling an error rather than quietly returning
seems useless. The only reason I can think of to signal an error in general
is if there was some danger to be avoided or more than one way you could
go and you want to allow user intervention. In this case, I think people
always do just one thing: say to themselves "oh, i guess I won't compile
this". We might as well let the system do it for them.
So my inclination is to say yes, that we should reopen the issue.
My understanding was that the primary justification of the previous proposal
over this one is that it was what you thought was the "best that could be
hoped for". My inclination is to believe that this raises the least common
denominator without crossing that line where we get bogged down in
capabilities of particular implementations, etc.
Does you (or does anyone) have reason to believe that the new proposal
I've just circulated would cause any kind of problem?
∂02-Jan-89 2209 CL-Compiler-mailer Re: issue COMPILE-ARGUMENT-PROBLEMS
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 2 Jan 89 22:09:39 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06748; Mon, 2 Jan 89 23:08:33 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05391; Mon, 2 Jan 89 23:08:31 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901030608.AA05391@defun.utah.edu>
Date: Mon, 2 Jan 89 23:08:30 MST
Subject: Re: issue COMPILE-ARGUMENT-PROBLEMS
To: cl-compiler@sail.stanford.edu
[Ooops, my reply to Kent's misdirected message got misdirected too.]
It looks to me like the main difference between the two proposals is
in the treatment of functions defined in a non-null lexical
environment. The proposal that was voted on was amended in accordance
with your earlier suggestions to make the other situations harmless --
doing nothing is an acceptable alternative if the function is already
compiled, but signalling errors or blowing fuses is not -- so I think
the other issues you touch upon in your new proposal could probably be
handled as editorial changes. I would much rather do that than re-open
the issue (I think our time would be better spent trying to deal with
the many other unresolved issues we still have pending), but if you
feel strongly about this then of course we can go ahead and ask for
another vote.
A problem I have with your proposal is that I believe that
COMPILED-FUNCTION-P must be true of any function returned from
COMPILE, and that COMPILE must also at least ensure that all macro
calls in the function have been expanded. I don't think that allowing
COMPILE to do nothing when passed an interpreted function is a
legitimate option.
I've actually been trying to draft a short document for Kathy Chapman
to describe the minimum functionality required for implementations of
COMPILE and COMPILE-FILE (incorporating Steve's famous "compiler
model" from last March), but if what's obvious to me isn't obvious to
other people, I should probably turn at least this one part of the
writeup into a new issue so we can vote on it formally.
-Sandra
-------
**** End of Forwarded Message ****
-------
∂02-Jan-89 2305 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Jan 89 23:05:47 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 514179; Tue 3-Jan-89 02:00:39 EST
Date: Tue, 3 Jan 89 02:00 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue COMPILER-DIAGNOSTICS, v7
To: IIM@ECLA.USC.EDU
cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: <12458958705.23.IIM@ECLA.USC.EDU>
Message-ID: <890103020001.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Sat 31 Dec 88 19:44:13-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
...
It seems reasonable to give the user a mechanism for controling that kind of
output too, but I don't really think of such messages as warnings. NOTICE
seems like a nice, simple thing to use to say that something is happening but
you can ignore it if you like, but maybe the name implies more priority than is
intended. Maybe some other name?
Part of my objection is that the name NOTICE is too vanilla.
There are other possible meanings and I can see people being bummed
if we use it up.
The Lisp Machine has a thing called a notification. I might be
susceptible to calling the type a NOTIFICATION and making a function
called NOTIFY. Then, at least, there would be current practice behind
the idea.
In another message, you suggested things like
Compiling FOO.
could be controlled by this, but there's already a competing proposal
for a :PRINT keyword to COMPILE-FILE which would cause that kind of
thing to go to STANDARD-OUTPUT (presumably unconditionally). I don't
want -too- many ways to do the same thing, so we should be careful about
our motivation.
If we made a notification facility, I think it should be done by Cleanup,
not compiler. Then perhaps GC messages could be done using it, and
the GC-MESSAGES issue (which deals with suppressing such messages) could
be handled as part of the same thing, too.
I don't have time to pursue this further and I can't say for sure that
if someone fleshed this out that I would necessarily support it ... but
I am not unalterably opposed to it if it's done in a way that motivates
its use (and doesn't just go in randomly with not even an initial purpose),
doesn't lock down too many short highly generic names, etc.
∂03-Jan-89 0118 CL-Compiler-mailer Re: Issue COMPILE-ARGUMENT-PROBLEMS
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 3 Jan 89 01:18:20 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 514199; Tue 3-Jan-89 04:02:34 EST
Date: Tue, 3 Jan 89 04:01 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue COMPILE-ARGUMENT-PROBLEMS
To: sandra%defun@cs.utah.edu
cc: CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: <8901030603.AA05373@defun.utah.edu>
Message-ID: <890103040152.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
[Note corrected address. Don't send mail on this topic to CL-Cleanup.]
Nothing prohibits an interpreted-only implementation from defining
that COMPILED-FUNCTION-P returns true for all objects of type function,
in spite of their interpretedness. Compiled functions have no property
other than that they are the subset of functions which the compiler wants
to consistently treat as compiled.
I don't agree that semantic changes should be made by "editorial discretion".
If we are going to change the conditions under which something may or
must signal an error, however slightly, I think it must go through a
proposal.
I will look back over my proposal and see what I think the difference is
between it and what was passed. I think there is more difference than
you suggest, but I'm susceptible to the idea that a smaller writeup might
suffice to accomodate the delta.
∂03-Jan-89 0857 CL-Compiler-mailer Re: Issue: DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 3 Jan 89 08:57:37 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA24884; Tue, 3 Jan 89 11:56:18 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA12946; Tue, 3 Jan 89 11:56:19 EST
Message-Id: <8901031656.AA12946@mist.>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: cl-compiler@sail.stanford.edu
Subject: Re: Issue: DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES
In-Reply-To: Your message of Fri, 30 Dec 88 17:43:00 -0500.
<19881230224313.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 03 Jan 89 11:56:16 EST
From: Dan L. Pierson <pierson@mist.encore.com>
I don't have any record of this issue being discussed. If I'm
coming in late, please ignore and forgive me.
There seemed to be some sentiment that it was just a minor editorial
correction, flavored with a touch of "but doesn't CLtL already require
this?". My carelessness about the error handling unfortunately
attracted more attention than the issue itself.
Date: Fri, 07 Oct 88 17:19:22 EDT
From: Dan L. Pierson <pierson%mist@multimax.ARPA>
Issue: DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES
References: Array type specifiers, pp. 45-46
Related issues: ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS, DECLARE-TYPE-FREE
I don't think this has any actual interactions with the issue
ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS, since
DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES is about ARRAY type specifiers for
declaration, while ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS is about ARRAY type
specifiers for discrimination.
When I first raised this issue, JonL responded that he agreed (though
he may now have changed his mind), but that
ARRAY-TYPE-ELEMENT-SEMANTICS wasn't the right issue. On the other
hand, I'll be happy to remove the references if you want.
Proposal (DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES:RESTRICTIVE):
Within the scope of an array type declaration, all references to array
elements are assumed to satisfy the exact declared element type.
That's reasonable. However, this is not a CLARIFICATION but a CHANGE,
since CLtL p.46 seems to be quite clear that the current meaning of such
a TYPE declaration is that the array elements satisfy the implementation
element type (what JonL calls the upgraded type), not the exact declared
element type. Since your proposed new definition is more restrictive,
some portable programs that used to be correct may now be in error, hence
this is an incompatible CHANGE. I think I'd vote for it anyway unless
someone argues that there is a significant impact on users.
Hmm, JonL seemed to think it was a CLARIFICATION, however your
arguments are convincing and this CHANGE is exactly what I want. It
seems to me that anything else violates the clearly stated intent of
the user.
An
implementation should signal an error if this is ever violated.
That's not reasonable. The status quo for type declarations is that
a violation "is an error". Changing it to "signals an error" is likely to
meet enormous resistance especially from stock hardware implementations,
and I think even changing it to "signals an error at the highest SAFETY
setting" would meet significant resistance.
Well, it certainly met significant controversy. I got a number of
strongly partisan responses on both sides of the question. Note that
the phrase in question is "should signal an error", which implies only
the interpreter and the safest compiler setting. The big oversight
here is that I carelessly introduced this part of the proposal as a
minor part of a different issue. While I would very much like to see
a compilation (and maybe interpretation) mode which check all type
declarations for violation and signals errors, I've become convinced
that this is something a few vendors should implement before it is
standardized. For one thing there's the question of when to check: on
-every- operation, on operations that would otherwise do a typecase?
The former may imply too much overhead for aanyone, the latter might
not catch many of the cases of this proposal.
∂03-Jan-89 0932 CL-Compiler-mailer Re: Compilation implications
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 3 Jan 89 09:32:02 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA25364; Tue, 3 Jan 89 09:33:49 PST
Received: from suntana.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA00274; Tue, 3 Jan 89 09:30:28 PST
Received: from localhost by suntana.sun.com (4.0/SMI-4.0)
id AA11579; Tue, 3 Jan 89 09:31:04 PST
Message-Id: <8901031731.AA11579@suntana.sun.com>
To: Jon L White <jonl@lucid.com>
Cc: kempf@Sun.COM, Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu, cperdue%suntana@Sun.COM
Subject: Re: Compilation implications
In-Reply-To: Your message of Fri, 30 Dec 88 20:07:12 -0800.
<8812310407.AA16126@bhopal>
Date: Tue, 03 Jan 89 09:31:00 PST
From: kempf@Sun.COM
>packages just as a consistency check. Unfortunately, I don't see how
>to evaluate the myriads of consistency checks that could conceivable be
>placed in a "dumped" class; would they be worth the effort?
The class redefinition protocol is probably the right way to go here.
If there is a difference between the instance structure in the file
and in memory, it could be called to update the instance.
>This is not a problem in Lucid Common Lisp [by the bye, I'm assuming a
>single COMPILE-FILE -- I'm not talking about the problem of separate file
Sorry, I should have said "in a portable way." There are some Lisps
(maybe all of them now) which maintain EQLness over FASL for things
other than characters, symbols, and numbers. But the language spec
in CLtL doesn't require it.
jak
∂03-Jan-89 0947 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 3 Jan 89 09:47:20 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA25785; Tue, 3 Jan 89 09:48:40 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA00912; Tue, 3 Jan 89 09:45:20 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA04355; Tue, 3 Jan 89 09:46:22 PST
Date: Tue, 3 Jan 89 09:46:22 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901031746.AA04355@clam.sun.com>
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK, sandra%defun@cs.utah.edu
Subject: Re: issue QUOTE-MAY-COPY, version 2
Cc: KMP@scrc-stony-brook.arpa, cl-compiler@sail.stanford.edu
> > Could it be that something like the following might return NIL?
> >
> > (let ((a (gensym)))
> > (eql (funcall (compile nil `(lambda () ',a)))
> > (funcall (compile nil `(lambda () ',a)))))
> >
> > Or even
> >
> > (let ((a (gensym)))
> > (eval `(eql ',a ',a)))
Let's leave QUOTE with its current definition, in which it does not
copy ever, and define both of these to always return "true". It shouldn't
even matter what type of object a is bound to.
>
> Rather than making an exception for gensyms, I'm inclined to believe
> that *all* sharing of structures within an expression passed to EVAL,
> a function passed to COMPILE, or the entire contents of a file
> compiled with COMPILE-FILE ought to be preserved. I don't think it
> would be unreasonable for your first example to return NIL, but I
> think the second one ought to return true (regardless of whether the
> value of A is a gensym or some other kind of object).
>
> This really falls under issue CONSTANT-CIRCULAR-COMPILATION . . .
Sandra's point, when applied to COMPILE-FILE, does indeed at least
overlap with CONSTANT-CIRCULAR-COMPILATION. Let's require sharing
to be preserved when *DUMP-CIRCLE* is turned on. How about that?
Also, it is important to understand that if the fasdumper
does not detect shared structure, as when *DUMP-CIRCLE* or the
equivalent is NOT turned on, the "inverse" of constant coalescing
occurs -- one object in the source may turn into 2 if it appears
in multiple places. I know that this point has been made
before, I'm just repeating it.
∂03-Jan-89 0955 CL-Compiler-mailer Re: environment arguments and compiler contexts and ...
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 3 Jan 89 09:55:40 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA26012; Tue, 3 Jan 89 09:57:15 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA01387; Tue, 3 Jan 89 09:53:56 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA04380; Tue, 3 Jan 89 09:54:59 PST
Date: Tue, 3 Jan 89 09:54:59 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901031754.AA04380@clam.sun.com>
To: IIM@ECLA.USC.EDU, sandra%defun@cs.utah.edu
Subject: Re: environment arguments and compiler contexts and ...
Cc: cl-compiler@SAIL.STANFORD.EDU
> . . . I suspect that an
> "industrial strength" program analyzer would want to have special
> knowledge about *most* built-in Common Lisp macros, rather than just
> expanding them blindly. The reason for this is that many compilers
> treat them as special forms, and while the macro expansions are
> correct, they are often much less efficient. . . .
There is also another problem in that the macros may expand into
calls to functions that are implementation-specific. Expanding
into implementation-dependent special forms is opposed in CLtL,
but *functions* are OK, and this is enough to make a program
analyzer ineffective unless it understands the defining macros
themselves.
∂03-Jan-89 1003 CL-Compiler-mailer Re: Issue COMPILER-DIAGNOSTICS, v7
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 3 Jan 89 10:03:02 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA25490; Tue, 3 Jan 89 13:01:47 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA13122; Tue, 3 Jan 89 13:01:48 EST
Message-Id: <8901031801.AA13122@mist.>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: cl-compiler@SAIL.STANFORD.EDU, cl-cleanup@sail.stanford.edu
Subject: Re: Issue COMPILER-DIAGNOSTICS, v7
In-Reply-To: Your message of Tue, 03 Jan 89 02:00:00 -0500.
Date: Tue, 03 Jan 89 13:01:46 EST
From: Dan L. Pierson <pierson@mist.encore.com>
[[Meta-note to cl-cleanup. One of the proposals for handling compiler
messages is based on signalling all messages as conditions with the
standard signalling function "printing" the message iff the
condition isn't handled. I think that this approach can, and
should, be applied to messages in the cleanup domain as well so I'm
forwarding just this message to cleanup to get a sense of the
sentiment there.]]
Part of my objection is that the name NOTICE is too vanilla.
There are other possible meanings and I can see people being bummed
if we use it up.
The Lisp Machine has a thing called a notification. I might be
susceptible to calling the type a NOTIFICATION and making a function
called NOTIFY. Then, at least, there would be current practice behind
the idea.
I have no objection to these name changes.
In another message, you suggested things like
Compiling FOO.
could be controlled by this, but there's already a competing proposal
for a :PRINT keyword to COMPILE-FILE which would cause that kind of
thing to go to STANDARD-OUTPUT (presumably unconditionally). I don't
want -too- many ways to do the same thing, so we should be careful about
our motivation.
That's true. I am mildly opposed to the competing proposal because
it's redundant with mine. I am strongly in favor of one general
condition-based mechanism for all of these messages.
If we made a notification facility, I think it should be done by Cleanup,
not compiler. Then perhaps GC messages could be done using it, and
the GC-MESSAGES issue (which deals with suppressing such messages) could
be handled as part of the same thing, too.
No object, since it also came up in connection with Moon's comments on
GC-MESSAGES, if forwarding this to cl-cleanup as well.
I don't have time to pursue this further and I can't say for sure that
if someone fleshed this out that I would necessarily support it ... but
I am not unalterably opposed to it if it's done in a way that motivates
its use (and doesn't just go in randomly with not even an initial purpose),
doesn't lock down too many short highly generic names, etc.
I can try to come up with something, if a condition-based approach to
this whole problem looks acceptable.
∂03-Jan-89 0959 Common-Lisp-Object-System-mailer Re: Compilation implications
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 3 Jan 89 09:59:35 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 514403; Tue 3-Jan-89 12:57:30 EST
Date: Tue, 3 Jan 89 12:56 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Compilation implications
To: kempf@Sun.COM
cc: Jon L White <jonl@lucid.com>, Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu, cperdue%suntana@Sun.COM
In-Reply-To: <8901031731.AA11579@suntana.sun.com>
Message-ID: <19890103175655.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 03 Jan 89 09:31:00 PST
From: kempf@Sun.COM
>packages just as a consistency check. Unfortunately, I don't see how
>to evaluate the myriads of consistency checks that could conceivable be
>placed in a "dumped" class; would they be worth the effort?
The class redefinition protocol is probably the right way to go here.
If there is a difference between the instance structure in the file
and in memory, it could be called to update the instance.
I thought you said you agreed with my proposal that the way to load an
instance of a standard-class from a compiled file is for a method of the
instance to return a form which is then evaluated at load time. Once
this is adopted, there is no such thing as "the instance structure in
the file" and no issue of making that structure consistent with some
other structure. The semantics of loading an instance of a standard-class
from a compiled file can be entirely understood in terms of MAKE-INSTANCE
or whatever other function is called by the form returned by MAKE-LOAD-FORM;
no new concepts need be introduced. If the programmer of a given class
wants to use the class redefinition protocol, that class's MAKE-LOAD-FORM
method can output something that uses that protocol, and if he doesn't,
it can output something that doesn't.
∂03-Jan-89 1029 CL-Compiler-mailer issue COMPILED-FUNCTION-REQUIREMENTS, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 3 Jan 89 10:29:29 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA20682; Tue, 3 Jan 89 11:28:17 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05809; Tue, 3 Jan 89 11:28:14 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901031828.AA05809@defun.utah.edu>
Date: Tue, 3 Jan 89 11:28:13 MST
Subject: issue COMPILED-FUNCTION-REQUIREMENTS, version 1
To: cl-compiler@sail.stanford.edu
This is a new issue.
Forum: Compiler
Issue: COMPILED-FUNCTION-REQUIREMENTS
References: CLtL p. 32, 76, 112, 143, 438-439
Issue FUNCTION-TYPE (passed)
Issue COMPILER-LET-CONFUSION
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue LOAD-TIME-EVAL
Category: CLARIFICATION
Edit History: V1, 3 Jan 1989 Sandra Loosemore
Status: **DRAFT**
Problem Description:
There is confusion about what functions might be or must be of type
COMPILED-FUNCTION, and what attributes must be true of
COMPILED-FUNCTIONs. Is the distinction between COMPILED-FUNCTIONs and
other functions only one of representation, or can user programs infer
anything about COMPILED-FUNCTIONs? Are implementations required to
distinguish between compiled and non-compiled functions?
CLtL defines a COMPILED-FUNCTION as "a compiled code object". (Issue
FUNCTION-TYPE says only that COMPILED-FUNCTION must be a subtype of
FUNCTION.) Although it is not explicitly stated, CLtL implies that
compiled code must conform to certain rules; in particular, it states
that all macros are expanded at compile time, and specifies different
behavior for the COMPILER-LET and the EVAL-WHEN special forms
depending on whether they are interpreted or compiled.
The description of COMPILE in CLtL says that "a compiled-function object
[is] produced". It is not clear to everyone whether this implies that
COMPILED-FUNCTION-P must be true of such functions. CLtL says nothing
about whether functions defined in files compiled with COMPILE-FILE and
subsequently loaded must be of type COMPILED-FUNCTION.
Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN:
(1) Clarify that if a function is of type COMPILED-FUNCTION, the
following are guaranteed about the function:
- All macro calls within the function have already been expanded
and will not be expanded again when the function is called.
(See CLtL p. 143.)
- Nested COMPILER-LETs will not bind any variables when the function
is called (CLtL p. 112).
- If the function contains nested EVAL-WHENs, only the LOAD (and not
the EVAL) situation is applicable.
- If the function contains nested LOAD-TIME-VALUE forms, these have
already been pre-evaluated and will not be evaluated again when
the function is called.
(2) Implementations are free to classify all functions as
COMPILED-FUNCTIONs, provided that all functions satisfy the criteria
listed in item (1). It is also permissible for interpreted FUNCTIONs
to satisfy the above criteria but not be distinguished as
COMPILED-FUNCTIONs.
(3) Clarify that COMPILE always produces an object of type
COMPILED-FUNCTION. Clarify that when functions are defined in a
file which is compiled with COMPILE-FILE, and the compiled file is
subsequently LOADed, objects of type COMPILED-FUNCTION result.
Rationale:
This proposal states what many people believe to be the minimum
functionality required of a compiler.
Current Practice:
It appears that most implementations currently distinguish compiled
versus non-compiled functions on the basis of representation, but it
seems unlikely that any existing implementation would have problems
with the requirements in item (1).
A-Lisp uses the same representation for both compiled and interpreted
functions and currently labels them both as COMPILED-FUNCTION, but the
implementation of COMPILED-FUNCTION-P could be easily fixed to
distinguish "real" compiled functions.
Cost to implementors:
Unknown, but probably small.
Cost to users:
Probably minimal. Since the COMPILED-FUNCTION type specifier is
currently ill-defined, it is hard to imagine that existing programs
can portably rely on any interpretation of what it means that is
inconsistent with what is presented here.
Benefits:
The specification of what the compiler must do is made more explicit.
Discussion:
Loosemore notes that the FIXNUM type was also defined in CLtL solely
on the basis of a distinguished representation from other INTEGERs,
and that this definition has proved inadequate for just about all
portable usages of the type specifier. Defining COMPILED-FUNCTION
solely on the basis of distinguished representation seems like a bad
idea.
-------
∂03-Jan-89 1153 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 3 Jan 89 11:53:47 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA23783; Tue, 3 Jan 89 12:52:40 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05860; Tue, 3 Jan 89 12:52:37 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901031952.AA05860@defun.utah.edu>
Date: Tue, 3 Jan 89 12:52:35 MST
Subject: issue QUOTE-MAY-COPY, version 3
To: cl-compiler@sail.stanford.edu
Here is the latest and greatest version. The major addition is that I
have greatly expanded the discussion section. The only change to the
proposal part is that I have added wording to clarify how this relates
to the the other proposals on constants, in response to an earlier
suggestion.
Forum: Compiler
Issue: QUOTE-MAY-COPY
References: CLtL p. 55, 78, 86, 143
Issue CONSTANT-COLLAPSING
Issue CONSTANT-COMPILABLE-TYPES
Issue CONSTANT-MODIFICATION
Category: CHANGE/CLARIFICATION
Edit History: V1, 5 Dec 1988, Sandra Loosemore
V2, 10 Dec 1988, Sandra Loosemore
(comments from Dalton, JonL)
V3, 3 Jan 1989, Sandra Loosemore
(comments from Pitman et al)
Status: **DRAFT**
Problem Description:
May QUOTE return a copy of its argument? In particular, is it
permissible for COMPILE to copy quoted constants to read-only
memory, or to coalesce equivalent constants?
Background:
CLtL p. 86 states that (QUOTE <x>) simply returns <x>. On
p. 55 it is mentioned that the only self-evaluating forms that may
be copied are numbers or characters. It is also stated that an
implementation is permitted to collapse (or coalesce) EQUAL constants
appearing in code to be compiled.
Because of its nature as a file processor, COMPILE-FILE generally must
cause copies of constants to be constructed when the compiled code is
loaded. In a number of existing Lisp implementations, COMPILE also
causes constant objects to be copied and/or coalesced. Since it is
permissible for an implementation to implicitly compile even
"interpreted" code (p. 143), the semantics of constants seen by EVAL
may also be affected if the in-memory compiler (as well as the file
compiler) is allowed to copy or coalesce constants.
The arguments for allowing constants to be copied can be summarized
briefly as follows. Copying constants to read-only memory can result
in less work for garbage collectors. If there is hardware support for
write-protection of memory, this may also be used to cause an error to
be signalled if an attempt is made to modify the constant. Coalescing
equivalent constants can lead to significant memory savings in some
applications (although this savings is likely to be less for individual
functions compiled with COMPILE than entire programs compiled with
COMPILE-FILE).
The primary argument against allowing constants to be copied or
coalesced is that doing so causes information to be lost, and in the
case of COMPILE and EVAL, there is no inherent reason why this
information must be discarded. Some people also feel that allowing
QUOTE not to return a value that is EQ (or even EQL) to its argument
would be a substantial, incompatible change from its "traditional"
semantics.
Proposal QUOTE-MAY-COPY:ALWAYS:
Change the description of QUOTE to indicate that (QUOTE <x>) returns
an object equivalent to <x>, which may or may not be EQ to <x>.
Likewise, a self-evaluating form may also return an equivalent copy
of the object.
The equivalence relationship is defined in the writeup for issue
CONSTANT-COMPILABLE-TYPES, and only those objects for which this
relationship is defined may appear as quoted or self-evaluating
constants. The restrictions placed on compiled constants in
issue CONSTANT-CIRCULAR-COMPILATION apply to constants in code
processed by EVAL and COMPILE, as well as COMPILE-FILE. EVAL and
COMPILE may also coalesce constants, as described in issue
CONSTANT-COLLAPSING.
If an implementation chooses to copy constants, the copying may only
happen once each time the form containing the constant is processed
with COMPILE or EVAL (see examples below).
Rationale:
This proposal would make the treatment of constants uniform across
COMPILE-FILE, COMPILE, and EVAL.
Proposal QUOTE-MAY-COPY:NOT-EVAL-OR-COMPILE:
Clarify that self-evaluating forms and quoted constants always
evaluate to objects that are EQL to the original, except in the case
of code compiled with COMPILE-FILE (where an equivalent but possibly
non-EQL object is returned). The restrictions on compiling constants
in issues CONSTANT-COMPILABLE-TYPES and CONSTANT-CIRCULAR-COMPILATION
apply only to COMPILE-FILE. Only COMPILE-FILE may coalesce constants
(issue CONSTANT-COLLAPSING).
Rationale:
This proposal is the most consistent with the semantics described in
CLtL. It would make the treatment of constants uniform across
COMPILE and EVAL.
Proposal QUOTE-MAY-COPY:NOT-EVAL:
Clarify that quoted or self-evaluating constants appearing in code
processed by EVAL must return an object that is EQL to the original.
In functions that have been compiled with COMPILE or code that has
been compiled with COMPILE-FILE, an equivalent (but possibly
non-EQL) copy of the object may be returned instead.
The equivalence relationship is defined in the writeup for issue
CONSTANT-COMPILABLE-TYPES, and only those objects for which this
relationship is defined may appear as quoted or self-evaluating
constants in code to be compiled. The restrictions on constants
described in issue CONSTANT-CIRCULAR-COMPILATION apply to both
COMPILE-FILE and COMPILE, and both may coalesce constants as
described in issue CONSTANT-COLLAPSING. There are no restrictions
on what kinds of objects may appear in code processed with EVAL, and
EVAL may not coalesce equivalent constants.
If an implementation chooses to copy constants, the copying may only
happen once each time the form containing the constant is processed
with COMPILE (see examples below).
Rationale:
This proposal is the most consistent with current practice.
Test Cases/Examples:
#1: (Behavior of COMPILE)
Suppose the function FOO is defined:
(defun foo () '(a b c))
Under all three proposals, multiple calls to FOO must always return
EQ values, regardless of whether FOO is interpreted or compiled:
(eq (foo) (foo)) ==> true
Proposals ALWAYS and NOT-EVAL allow FOO to return a "different" EQ
value after it is compiled:
(setq old-foo (foo))
(compile 'foo)
(eq old-foo (foo)) ==> ??? under ALWAYS or NOT-EVAL
true under NOT-EVAL-OR-COMPILE
#2: (Behavior of EVAL)
(let ((x '(a b c)))
(eq x
(eval (list 'quote x))))
Under proposal ALWAYS, this may or may not return true. Proposals
NOT-EVAL-OR-COMPILE and NOT-EVAL guarantee this to return true.
(let ((x '(a b c)))
(eq (eval (list 'quote x))
(eval (list 'quote x))))
Under proposal ALWAYS, this may or may not return true (each call to
EVAL may construct its own copy of X). Proposals NOT-EVAL-OR-COMPILE
and NOT-EVAL guarantee this to return true.
Current Practice:
Implementations in which COMPILE copies constants include PSL/PCLS and
Kyoto Common Lisp. In Lucid Common Lisp, constants are not normally
copied by COMPILE, but since COMPILE does coalesce constants, it may
cause QUOTE to return an object which is not EQL to its original
argument.
There do not appear to be any implementations in which constants are
copied by EVAL.
Cost to implementors:
Proposal QUOTE-MAY-COPY:NOT-EVAL-OR-COMPILE would cause significant
problems for some implementations. For example, PSL/PCLS would
require major changes to its memory management scheme and garbage
collector as well as the compiler to bring it into compliance.
Proposal QUOTE-MAY-COPY:NOT-EVAL could potentially cause problems for
compiled-only implementations in which the in-memory compiler normally
coalesces or makes copies of constants. There does not appear to be
any existing implementation that would be affected.
Note that neither QUOTE-MAY-COPY:ALWAYS or QUOTE-MAY-COPY:NOT-EVAL
-require- constants to be copied or coalesced; neither proposal would
require changes to those implementations that currently don't touch
constants.
Cost to users:
Proposals QUOTE-MAY-COPY:ALWAYS and QUOTE-MAY-COPY:NOT-EVAL would have
the result of explicitly stating that programs which depend on COMPILE
preserving EQLness of constants are nonportable. (This is the de
facto situation now.) Such programs could continue to work in those
implementations in which COMPILE does not copy or coalesce constants.
The impact of allowing constants to be copied in interpreted code
(proposal QUOTE-MAY-COPY:ALWAYS) is unknown. It could be argued that
any code that depends on constants not being copied or coalesced is
broken, since it would not work when compiled in some implementations.
Benefits:
The semantics of QUOTE are clarified.
Discussion:
There has been some confusion about the names of the proposals. Note
that proposal QUOTE-MAY-COPY:ALWAYS implies that copying is always
*permitted*, but is not required under any circumstances.
This issue has caused a very lengthy debate on the cl-compiler mailing
list, with no consensus arising yet. Following are comments
summarizing various people's positions.
Jeff Dalton says:
Just to make this clear, I currently favor [proposal NOT-EVAL-OR-COMPILE]:
would like to have EQL-identity preserved except when file operations
are involved.
Kent Pitman originally supported NOT-EVAL-OR-COMPILE, but now says:
I asked Moon about his feelings on this. He thinks pretty strongly that
the ALWAYS option is the only practical one to pursue. Partly, he says,
because it's maximally compatible with current practice and partly
because it avoids making COMPILE-FILE seem different.
In principle, I favor option ALWAYS, permitting copying of quoted
structure to a constants area in any of EVAL, COMPILE, or COMPILE-FILE
situations, as appropriate to the implementation.
It should not be concluded from this that I favor restrictions on the
kinds of data which may be quoted, however. The wording of option ALWAYS
should be ammended to say that such copying is permitted only when the
system can reliably deduce whether such copying is `appropriate,'
and avoid it in cases where it is not. The purpose of such wording would
be to avoid placing restrictions on what kinds of structures a user can
or cannot quote.
So, for example, if an implementor cannot in some context figure out how
to detect circularities in quoted structure in order to either decline
copying or correctly copy the circular form, then the implementation is
not permitted to attempt copying in such contexts.
Note however that because of special considerations forced by the external
representation of data in compiled files, I go along with (and encourage)
the establishment of a known subset of types which can be quoted (or used
as self-evaluating constants) in code to be reliably processed by the file
compiler. Coincidentally, such restrictions might make it easier for an
implementation to know whether copying was going to succeed in the case of
loading compiled code from a file, but technically these restrictions are
not motivated by any consideration of what kinds of structures might or
might not be possible to QUOTE.
My inclination is also to believe that copying should not be done
repeatedly, and we should find a way to express this. That is, repeated
execution of code in the same execution environment should return an EQL
result (or some such). This is important to guaranteeing efficiency. Even
in copying implementations, it is not necessary that such constants be
allocated in a read-only area or some such to achieve this effect. For
example, quoted structure could be placed in a special array and QUOTE
could be implemented using AREF. What is important is that any of these
permissions we give for copying not be taken for a license that QUOTE
should be implemented by COPY-TREE or some other operation which cannot
be done in constant time.
Dan Pierson says:
I also support QUOTE-MAY-COPY:NOT-EVAL-OR-COMPILE. In the absence of
overwhelming opposing reasons, we should not diminish traditional Lisp
functionality. While NOT-EVAL may be more in line with current
practice of a couple of implementations, the argument that these
implementations are already broken is at least as strong as the
argument that we shouldn't break them by pointing out that they don't
conform to the language standard.
However, my position on this is not unalterable.
Sandra Loosemore says:
I oppose NOT-EVAL-OR-COMPILE on the grounds that it differs from current
practice and would involve a substantial conversion cost for some
implementations; either of the other two alternatives would be acceptable
instead since they involve essentially no conversion cost for either
implementors or users. I am not convinced that the modifications to
proposal ALWAYS suggested by Pitman wouldn't cause just as much work
for some implementations as forbidding copying entirely. If the
modifications applied only to the behavior of EVAL and not COMPILE, that
would be OK.
Many people have referred to "tradition" in their arguments on this
issue. Different implementations have different traditions, and what
seems "broken" to one person may seem perfectly natural to another
person who comes from a different background.
JonL White says:
I favor giving as much leeway as possible to
the implementors for making memory-management optimizations. While one
implementor may choose not to do any such work, and another may even go
out of his way to assure EQLness over an unlikely set of circumstances,
this should not constrain the third from doing the "classic" thing. In
short, I don't see the value of adding constraints that
(1) invalidate much existing practice, and
(2) appear to be purely of theortical value.
Making "compiled code" (read: compile-file) work as closely as possible to
interpreted code is _not_ "purely of theortical value."
QUOTE-MAY-COPY:ALWAYS is the only proposal that both recognizes the
prevalent practice and pays (at least) lip service to the question of
compiled/interpreted consistency.
Cris Perdue notes:
My personal intuition is that (potentially) readonly constants are
created sometime during loading of a compiled file, and that as far
as a user of the language is concerned, the constants are *created*
in their coalesced, copied, readonly, or whatever state.
There may be other self-consistent and reasonable points of view. This
point of view makes sense to me, fits CLtL's existing specification of
QUOTE, and I think satisfies Pitman's concerns.
-------
∂03-Jan-89 1256 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 3 Jan 89 12:56:05 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA25984; Tue, 3 Jan 89 13:55:00 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05944; Tue, 3 Jan 89 13:54:57 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901032054.AA05944@defun.utah.edu>
Date: Tue, 3 Jan 89 13:54:56 MST
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: cl-compiler@sail.stanford.edu
Here's a new version incorporating a new proposal and Cris's suggested
change to the FLAG proposal.
Forum: Compiler
Issue: CONSTANT-CIRCULAR-COMPILATION
References: Issue CONSTANT-COLLAPSING
Issue QUOTE-MAY-COPY
Category: CLARIFICATION, ADDITION
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 14 Nov 1988, Cris Perdue
V3, 12 Dec 1988, Sandra Loosemore (merge versions 1 and 2)
V4, 03 Jan 1989, Sandra Loosemore (add PRESERVE-SHARING-ONLY)
Status: **DRAFT**
Problem Description:
CLtL does not specify whether constants containing circular or
recursive references may be compiled, or whether the compiler must
preserve sharing of EQ substructures.
The proposals below apply to COMPILE-FILE, since it must inherently
copy structures. If issue QUOTE-MAY-COPY is resolved in favor of
allowing COMPILE and possibly EVAL to copy structures, the same
constraints would also apply in those situations. [We would also have
to decide upon the scope over which sharing must be detected in such
situations; the minimal scope would be over a single call to EVAL or
COMPILE.]
Proposal CONSTANT-CIRCULAR-COMPILATION:NO
State that it is an error for an object containing a circular reference to
appear as a constant to be compiled. State that the compiler is not
required to preserve EQness of substructures.
Rationale:
This proposal would not require any existing implementation to change.
Disallowing portable programs from containing circular constants
allows compiled file loaders to use somewhat simpler implementation
strategies (for example, to build constants in a strict bottom-up
fashion).
Proposal CONSTANT-CIRCULAR-COMPILATION:PRESERVE-SHARING-ONLY
State that it is an error for an object containing a circular
reference to appear as a constant to be compiled. State that the
compiler is required to preserve EQness of substructures within a file
compiled with COMPILE-FILE.
Rationale:
Disallowing portable programs from containing circular constants
allows compiled file loaders to use somewhat simpler implementation
strategies (for example, to build constants in a strict bottom-up
fashion).
Some programs (such as PCL) have come to depend on COMPILE-FILE
preserving the EQness of uninterned symbols, and it is cleaner
to requiring sharing to be preserved in general instead of making
symbols be a special case. Requiring sharing to be preserved still
allows loaders to build constants bottom-up.
Proposal: CONSTANT-CIRCULAR-COMPILATION:FLAG
Add to the definition of Common Lisp a special variable:
*DUMP-CIRCLE* [Special variable]
State that if the (compile-time) value of *DUMP-CIRCLE* is NIL, it is
an error for an object containing a circular reference to appear as a
constant to be compiled. State that the compiler is required to
preserve EQness of substructures within a file compiled with
COMPILE-FILE when *DUMP-CIRCLE* is non-NIL. (Note that this differs
from *PRINT-CIRCLE*, which is not required to detect sharing.)
The initial value of *DUMP-CIRCLE* is implementation-dependent.
Rationale:
As with *PRINT-CIRCLE* for printing, writing representations of
objects to a stream is much faster if the implementation does not
attempt to support circular, self-recursive, mutually-referential,
etc. substructure.
Current Practice:
A-Lisp preserves EQness of substructures (since it makes an effort to
collapse isomorphic structures) but signals an error if an attempt is
made to compile a circular constant. PSL and Utah Common Lisp both
get stuck in an infinite loop if an attempt is made to compile a
reentrant structure. The TI Explorer compiler is able to reproduce
recursive lists and arrays, but currently hangs in a loop on a
circular list. Lucid and Symbolics can handle circular constants
correctly. Franz uses a flag to control whether or not to attempt to
detect circular constants.
Cost to implementors:
We know of no implementation that would have to change under proposal
NO. For proposal FLAG, some implementations would require sweeping
changes; in some cases a completely different dumper/loader strategy
would have to be implemented. The cost of proposal
PRESERVE-SHARING-ONLY would fall somewhere in between.
Cost to users:
The situation now is that programs which depend upon circularity or
sharing of substructure being preserved by the compiler are already
nonportable. Proposal NO simply formalizes the status quo. Proposal
FLAG would offer users functionality that is currently not portable.
Benefits:
An area of ambiguity in the language is removed.
Discussion:
JonL has argued against proposal CONSTANT-CIRCULAR-COMPILATION:NO, saying
I don't see any performance justification; and even if there were, I'd
look at it with a very jaundiced eye, favoring interpreter/compiler
consistency over nickle-and-dime issues of compiler speed.
Loosemore thinks PRESERVE-SHARING-ONLY is the "right" solution, but
would also support CONSTANT-CIRCULAR-COMPILATION:NO because it is the
most consistent with current practice -- no implementations would be
required to change and no currently portable programs would be
invalidated. While one could make an argument for this proposal on
the basis of improving compiler speed, the compatibility issue is seen
as far more important.
There was also quite a bit of discussion about how this proposal
relates to the requirement in CLtL (p. 69) about preserving the
EQLness of references to symbolic constants.
-------
∂03-Jan-89 1303 CL-Compiler-mailer issue CONSTANT-COLLAPSING, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 3 Jan 89 13:03:44 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA26374; Tue, 3 Jan 89 14:02:39 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA05952; Tue, 3 Jan 89 14:02:36 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901032102.AA05952@defun.utah.edu>
Date: Tue, 3 Jan 89 14:02:35 MST
Subject: issue CONSTANT-COLLAPSING, version 3
To: cl-compiler@sail.stanford.edu
Only minor tweaks here, to clarify the relationship of this proposal to
issues CONSTANT-COMPILABLE-TYPES and QUOTE-MAY-COPY.
Forum: Compiler
Issue: CONSTANT-COLLAPSING
References: CLtL p. 78, 87
Issue CONSTANT-MODIFICATION
Issue CONSTANT-COMPILABLE-TYPES
Issue EQUAL-STRUCTURE
ISsue QUOTE-MAY-COPY
Category: CHANGE
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 12 Dec 1988, Sandra Loosemore
V3, 03 Jan 1989, Sandra Loosemore
Status: **DRAFT**
Problem Description:
CLtL states that an implementation is permitted to "collapse" or
coalesce constants appearing in code to be compiled if they are EQUAL.
The definition of EQUAL does not permit coalescing of more general
isomorphic data structures (such as arrays and structures), which is
often desirable.
Issue QUOTE-MAY-COPY deals with whether coalescing may be performed
only by COMPILE-FILE, or by COMPILE and EVAL as well. CLtL says: "An
object is considered to be a constant in code to be compiled if it is
a self-evaluating form or contained in a QUOTE form".
Proposal CONSTANT-COLLAPSING:GENERALIZE:
State the an implementation is permitted to "collapse" constants
appearing in code to be compiled if they are equivalent under the
relationship specified in issue CONSTANT-COMPILABLE-TYPES.
Rationale:
There is little reason why implementations should not be allowed to
perform more general collapsing of structures, since the arguments
against doing so also apply to collapsing of EQUAL structures, which
is already permitted.
Current Practice:
Both PSL/PCLS and A-Lisp collapse isomorphic arrays and structures,
and certain other data types that are defined internally as structures
(RANDOM-STATEs, for example). Lucid Common Lisp also uses a more
general coalescing predicate than EQUAL.
Cost to implementors:
None. This extends the range of permitted behavior for
implementations but does not require any implementation to change.
Cost to users:
It is hard to imagine a program that would break under this proposal.
The EQL-ness or uniqueness of composite structures in compiled code
cannot be guaranteed in any event, since the combination of
COMPILE-FILE and LOAD generally results in a copy of the original
structure.
Benefits:
Collapsing of isomorphic arrays and structures may lead to significant
memory savings in some applications.
Discussion:
This proposal depends heavily on issue CONSTANT-COMPILABLE-TYPES.
Some people believe that if the definition of EQUAL weren't "broken",
there wouldn't be any need for this proposal.
There is no inherent reason why the "coalescing predicate" must be the
same as the relationship used by the compiler/loader to construct
equivalent copies of objects of constants, but making the same rules
be applied in both situations simplifies the language somewhat.
-------
∂03-Jan-89 1409 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 3
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 3 Jan 89 14:09:14 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA02269; Tue, 3 Jan 89 14:11:04 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA13922; Tue, 3 Jan 89 14:07:39 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA04733; Tue, 3 Jan 89 14:08:41 PST
Date: Tue, 3 Jan 89 14:08:41 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901032208.AA04733@clam.sun.com>
To: cl-compiler@sail.stanford.edu
Subject: Re: issue QUOTE-MAY-COPY, version 3
I am opposed to all of the proposals offered in their current
form.
CLtL takes a simple, useful approach to this problem. The idea
that QUOTE cannot reasonably operate as defined in CLtL is incorrect,
though it appears desirable to explain somewhere the "copying"
effects that compile-file may have on constants.
To say that QUOTE copies in existing implementations is to
imply that a lot of copying might happen that never actually
happens. COMPILE-FILE followed by LOAD effectively copies,
and in KCL, COMPILE effectively makes a copy, but not QUOTE.
I object strongly to suggestions that QUOTE copies in existing
practice, at least existing practice as I know it. Among other things,
this skews the entire discussion. It also limits the set of datatypes
that can be QUOTEd, because the equivalence defined in
CONSTANT-COMPILABLE-TYPES does not support all datatypes.
It is possible for QUOTE or a garbage collector to copy
constants into readonly storage, but I think that rationale is
different from supporting existing practice. With that rationale
I might support something like QUOTE-MAY-COPY:ALWAYS, but I think
it would be questionable whether the equivalence defined in
CONSTANT-COMPILABLE-TYPES is sufficient. A version
that applies to all objects might be advisable as the equivalence
maintained by QUOTE.
∂03-Jan-89 1459 CL-Compiler-mailer issue ALLOW-LOCAL-INLINE
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 3 Jan 89 14:59:26 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Tue, 3 Jan 89 17:30:58 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Tue, 3 Jan 89 17:56:06 EST
Date: Tue, 3 Jan 89 17:56 EST
From: Barry Margolin <barmar@Think.COM>
Subject: issue ALLOW-LOCAL-INLINE
To: cl-compiler@sail.stanford.edu
In-Reply-To: <8901032223.AA06032@defun.utah.edu>
Message-Id: <19890103225604.1.BARMAR@OCCAM.THINK.COM>
This reminds me of my favorite issue about INLINE declarations. How do
you ask for a lexical function to be compiled inline? E.g.
(flet ((frob (x)
(1+ (car x))))
...
(frob foo))
Should a (declare (inline frob)) at the beginning of the FLET body
request that FROB be open-coded within the body?
barmar
∂03-Jan-89 1506 CL-Compiler-mailer issue QUOTE-MAY-COPY, version 3
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 3 Jan 89 15:05:59 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA03621g; Tue, 3 Jan 89 15:02:18 PST
Received: by bhopal id AA29591g; Tue, 3 Jan 89 15:04:29 PST
Date: Tue, 3 Jan 89 15:04:29 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901032304.AA29591@bhopal>
To: cperdue@Sun.COM
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Cris Perdue's message of Tue, 3 Jan 89 14:08:41 PST <8901032208.AA04733@clam.sun.com>
Subject: issue QUOTE-MAY-COPY, version 3
re: To say that QUOTE copies in existing implementations is to
imply that a lot of copying might happen that never actually
happens. COMPILE-FILE followed by LOAD effectively copies,
and in KCL, COMPILE effectively makes a copy, but not QUOTE.
This may be repeating previous points, but we've been maintaing that
the phrase "QUOTE copies" does *not* mean that the function QUOTE
does any work -- merely that the semantics of "quoted objects" is such
that you cannot tell whether you got the "original" or some copy
thereof.
-- JonL --
∂03-Jan-89 1516 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 3 Jan 89 15:16:12 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA02174; Tue, 3 Jan 89 16:13:10 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06127; Tue, 3 Jan 89 16:12:46 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901032312.AA06127@defun.utah.edu>
Date: Tue, 3 Jan 89 16:12:45 MST
Subject: Re: issue ALLOW-LOCAL-INLINE
To: Barry Margolin <barmar@Think.COM>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Barry Margolin <barmar@Think.COM>, Tue, 3 Jan 89 17:56 EST
> Date: Tue, 3 Jan 89 17:56 EST
> From: Barry Margolin <barmar@Think.COM>
>
> Should a (declare (inline frob)) at the beginning of the FLET body
> request that FROB be open-coded within the body?
My interpretation of the cl-cleanup issue DECLARATION-SCOPE is that an
INLINE declaration for a function defined with FLET or LABELS does
apply to that local function, and the declaration has exactly the same
scope as the function. Presumably one could use LOCALLY to declare it
NOTINLINE if one wanted to avoid having it coded inline in some parts
of the body.
-Sandra
-------
∂03-Jan-89 1525 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 3 Jan 89 15:24:56 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA03650g; Tue, 3 Jan 89 15:21:06 PST
Received: by bhopal id AA29766g; Tue, 3 Jan 89 15:23:06 PST
Date: Tue, 3 Jan 89 15:23:06 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901032323.AA29766@bhopal>
To: IIM@ECLA.USC.EDU
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett's message of Mon 2 Jan 89 17:28:34-PST <12459458298.4.IIM@ECLA.USC.EDU>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
re: Now the real question is, is this really what we want to do?
Well, about a year ago, I became convinced that "we" out to give a
macro-definition for EVAL-WHEN, to greatly simplify it's description.
Your recent addition to the previous proposals for this macro is the
one that makes the COMPILE situation only relevant to "toplevel"; it
does make the coding a bit simpler.
A year ago, I might have been opposed to that simply because it meant
that "toplevel" would have to be rigorously defined, and I didn't think
it could be done in time. But it looks like we *are* going to have to
do it anyway. So we might as well go for the simplification you inspired.
-- JonL --
∂03-Jan-89 1530 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 3 Jan 89 15:30:53 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA03656g; Tue, 3 Jan 89 15:26:50 PST
Received: by bhopal id AA29858g; Tue, 3 Jan 89 15:29:01 PST
Date: Tue, 3 Jan 89 15:29:01 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901032329.AA29858@bhopal>
To: sandra%defun@cs.utah.edu
Cc: IIM@ECLA.USC.EDU, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Sandra J Loosemore's message of Mon, 2 Jan 89 21:56:42 MST <8901030456.AA05311@defun.utah.edu>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
re:
(eval-when (eval compile load)
(eval-when (eval compile load)
(punch-paper-tape)))
Yes, I too feel that it is absolutely unacceptable for PUNCH-PAPER-TAPE to
be called twice at compile time. Still, as far as other processing
goes, (PUNCH-PAPER-TAPE) must appear to be "at toplevel". Hmmmm, maybe
KIM's solution still doesn't dispense with the need to do a MACROLET
on EVAL-WHEN so that nested eval-whens can have the correct semantics.
-- JonL --
∂03-Jan-89 1613 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 3 Jan 89 16:13:48 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA03664; Tue, 3 Jan 89 17:02:03 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06193; Tue, 3 Jan 89 17:01:55 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901040001.AA06193@defun.utah.edu>
Date: Tue, 3 Jan 89 17:01:54 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: Jon L White <jonl@lucid.com>
Cc: sandra%defun@cs.utah.edu, IIM@ECLA.USC.EDU, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Jon L White <jonl@lucid.com>, Tue, 3 Jan 89 15:29:01 PST
> Date: Tue, 3 Jan 89 15:29:01 PST
> From: Jon L White <jonl@lucid.com>
>
> Hmmmm, maybe KIM's solution still doesn't dispense with the need to do
> a MACROLET on EVAL-WHEN so that nested eval-whens can have the correct
> semantics.
Gag! Retch! :-)
Seriously, I think it would be an extremely bad idea to make
EVAL-WHEN's notion of when to perform compile-time magic different
than the standard notion of top-level-ness. Besides it being
confusing, one wouldn't be able to use EVAL-WHEN to implement the
magical compile-time behavior of the various defining macros. I
suppose that if we made the defining macros behave the same way, it
would be somewhat more reasonable, but in that case why not just
change the definition of top-level?
-Sandra
-------
∂03-Jan-89 1641 CL-Compiler-mailer issue DEFCONSTANT-SPECIAL
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 3 Jan 89 16:40:39 PST
Return-Path: <barmar@fafnir.think.com>
Received: from sauron.think.com by Think.COM; Tue, 3 Jan 89 19:00:36 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Tue, 3 Jan 89 19:26:09 EST
Date: Tue, 3 Jan 89 19:26 EST
From: Barry Margolin <barmar@Think.COM>
Subject: issue DEFCONSTANT-SPECIAL
To: cl-compiler@sail.stanford.edu
In-Reply-To: <8901032226.AA06038@defun.utah.edu>
Message-Id: <19890104002606.3.BARMAR@OCCAM.THINK.COM>
Forum: Compiler
Issue: DEFCONSTANT-SPECIAL
Edit History: V1, 15 Nov 1988, Sandra Loosemore
V2, 22 Nov 1988, Sandra Loosemore
V3, 30 Dec 1988, Sandra Loosemore
Rationale:
... One serious problem
that might arise from allowing constants to be rebound lexically is
that it would not be reliable to include symbolic constants in macro
expansions, because the user might have rebound them to something
else.
This is the same as the "hygienic macro" problem that exists with
lexical function names, and which exists with ordinary lexical variables
bound by a macro expansion that doesn't use GENSYM. The only concession
we've made to this problem in the past is the proposal to make binding
function/macro names that are defined by the CL spec undefined.
I agree that we should prohibit binding of constants, but I don't think
the above is a particularly strong reason. In any case, nothing in the
rationale addresses the issue of whether constants should be special or
not, which is the point of the proposal. Since the only thing that a
special declaration affects is the result of binding the variable, and
that is already disallowed, there's no real need to specify this. As
they say, "a difference that make's no difference is no difference."
barmar
∂03-Jan-89 1647 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 3 Jan 89 16:46:47 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Tue, 3 Jan 89 19:16:06 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Tue, 3 Jan 89 19:42:31 EST
Date: Tue, 3 Jan 89 19:42 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Re: issue ALLOW-LOCAL-INLINE
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8901032312.AA06127@defun.utah.edu>
Message-Id: <19890104004232.4.BARMAR@OCCAM.THINK.COM>
Date: Tue, 3 Jan 89 16:12:45 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Tue, 3 Jan 89 17:56 EST
> From: Barry Margolin <barmar@Think.COM>
>
> Should a (declare (inline frob)) at the beginning of the FLET body
> request that FROB be open-coded within the body?
My interpretation of the cl-cleanup issue DECLARATION-SCOPE is that an
INLINE declaration for a function defined with FLET or LABELS does
apply to that local function, and the declaration has exactly the same
scope as the function. Presumably one could use LOCALLY to declare it
NOTINLINE if one wanted to avoid having it coded inline in some parts
of the body.
I agree that it applies to that binding, but is that enough? In the
case of a global function, doing the PROCLAIM after the DEFUN would also
apply to that binding, but it doesn't have the desired effect because of
temporal issues.
In particular, putting an inline declaration of a local function at the
beginning of the FLET body doesn't have any effect in the Symbolics
implementation, which normally implements inline functions. It does
work in Lucid, though.
barmar
∂03-Jan-89 1756 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 3 Jan 89 17:56:40 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA07101; Tue, 3 Jan 89 18:53:34 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06263; Tue, 3 Jan 89 18:52:31 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901040152.AA06263@defun.utah.edu>
Date: Tue, 3 Jan 89 18:52:30 MST
Subject: Re: issue ALLOW-LOCAL-INLINE
To: Barry Margolin <barmar@Think.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>,
cl-compiler@sail.stanford.edu
In-Reply-To: Barry Margolin <barmar@Think.COM>, Tue, 3 Jan 89 19:42 EST
> I agree that it applies to that binding, but is that enough? In the
> case of a global function, doing the PROCLAIM after the DEFUN would also
> apply to that binding, but it doesn't have the desired effect because of
> temporal issues.
I don't think there's a problem. Unlike the DEFUN/PROCLAIM situation,
in the FLET example the definition of the function and the INLINE
declaration are simultaneous. It's more analogous to a SPECIAL
declaration in a LET, where the compiler has both the list of
variables to be bound and the declarations available to decide whether
the bindings should be special or lexical. Here, the compiler has
both the list of functions to be bound and the declarations available
to decide whether or not to save inlining information about each of
the functions.
Remember that compilers are always free to ignore INLINE declarations.
There is nothing wrong with Symbolics ignoring INLINE declarations for
local functions (as long as it doesn't try to substitute an inline
definition for a global function of the same name!).
-Sandra
-------
∂03-Jan-89 1838 CL-Compiler-mailer Re: Compilation implications
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 3 Jan 89 18:38:08 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA01222; Tue, 3 Jan 89 18:39:10 PST
Received: from suntana.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA23845; Tue, 3 Jan 89 18:35:50 PST
Received: from localhost by suntana.sun.com (4.0/SMI-4.0)
id AA11798; Tue, 3 Jan 89 18:36:27 PST
Message-Id: <8901040236.AA11798@suntana.sun.com>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: kempf@Sun.COM, Jon L White <jonl@lucid.com>,
Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu, cperdue%suntana@Sun.COM
Subject: Re: Compilation implications
In-Reply-To: Your message of Tue, 03 Jan 89 12:56:00 -0500.
<19890103175655.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 03 Jan 89 18:36:24 PST
From: kempf@Sun.COM
>thought you said you agreed with my proposal that the way to load an
>instance of a standard-class from a compiled file is for a method of the
>instance to return a form which is then evaluated at load time. Once
>this is adopted, there is no such thing as "the instance structure in
>the file" and no issue of making that structure consistent with some
>other structure. The semantics of loading an instance of a standard-class
Right. In general, this will be the case, but remember that your proposal
leaves open a programmer hook which may, in specific instances, require
the class redefinition protocol to be run. However, they will probably
be rare, so we can disregard them for now.
jak
∂03-Jan-89 1908 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 3 Jan 89 19:07:57 PST
Return-Path: <barmar@fafnir.think.com>
Received: from sauron.think.com by Think.COM; Tue, 3 Jan 89 20:51:11 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Tue, 3 Jan 89 21:18:31 EST
Date: Tue, 3 Jan 89 21:18 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Re: issue ALLOW-LOCAL-INLINE
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8901040152.AA06263@defun.utah.edu>
Message-Id: <19890104021829.7.BARMAR@OCCAM.THINK.COM>
Date: Tue, 3 Jan 89 18:52:30 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> I agree that it applies to that binding, but is that enough? In the
> case of a global function, doing the PROCLAIM after the DEFUN would also
> apply to that binding, but it doesn't have the desired effect because of
> temporal issues.
I don't think there's a problem. Unlike the DEFUN/PROCLAIM situation,
in the FLET example the definition of the function and the INLINE
declaration are simultaneous. It's more analogous to a SPECIAL
declaration in a LET, where the compiler has both the list of
variables to be bound and the declarations available to decide whether
the bindings should be special or lexical. Here, the compiler has
both the list of functions to be bound and the declarations available
to decide whether or not to save inlining information about each of
the functions.
Remember that compilers are always free to ignore INLINE declarations.
There is nothing wrong with Symbolics ignoring INLINE declarations for
local functions (as long as it doesn't try to substitute an inline
definition for a global function of the same name!).
-Sandra
-------
Sounds reasonable to me. I was just looking for confirmation that I
have just cause to request this as an enhancement to the Symbolics
compiler, and that I would be asking for it in the right form.
barmar
∂04-Jan-89 0312 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 4 Jan 89 03:12:47 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa03632; 4 Jan 89 10:47 GMT
Date: Tue, 3 Jan 89 17:06:28 GMT
Message-Id: <29418.8901031706@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
To: sandra <@cs.utah.edu:sandra@defun>, cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 31 Dec 88 13:23:20 MST
> The order in which non-top-level subforms of a top-level form are
> processed by the compiler is explicitly left unspecified.
I'm still not sure what this is about. Can you give an example?
∂04-Jan-89 0315 CL-Compiler-mailer Re: Issue COMPILER-LET-CONFUSION, v3
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 4 Jan 89 03:14:52 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa03636; 4 Jan 89 10:48 GMT
Date: Tue, 3 Jan 89 17:17:17 GMT
Message-Id: <29438.8901031717@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue COMPILER-LET-CONFUSION, v3
To: "Kim A. Barrett" <IIM@ecla.usc.edu>, cl-compiler@sail.stanford.edu
In-Reply-To: Kim A. Barrett's message of Sat 31 Dec 88 19:37:21-PST
> And some of us do. I freely admit that COMPILER-LET is rarely used, and
> probably even more rarely used correctly because it isn't well documented.
Is there a way to make COMPILER-LET work correctly short of requiring
that interpreters do a macroexpansion prepass? Right now, I can't use
COMPILER-LET in portable code because some macroexpansions happen after
the dynamic extent of the COMPILER-LET bindings has ended.
∂04-Jan-89 0801 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
Received: from cs.utah.edu ([128.110.4.21]) by SAIL.Stanford.EDU with TCP; 4 Jan 89 08:01:12 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA21347; Wed, 4 Jan 89 09:00:02 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06639; Wed, 4 Jan 89 08:59:54 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901041559.AA06639@defun.utah.edu>
Date: Wed, 4 Jan 89 08:59:53 MST
Subject: Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: sandra <sandra%defun@cs.utah.edu>, cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Tue, 3 Jan 89 17:06:28 GMT
Suppose I have the example from CLtL:
(let ((old-count *access-count*))
(unwind-protect
(progn
(incf *access-count*)
(perform-access))
(setq *access-count* old-count)))
This is entirely equivalent to:
(let ((old-count *access-count*))
(let ((thunk #'(lambda () (setq *access-count* old-count))))
(unwind-protect
(progn
(incf *access-count*)
(perform-access))
(funcall thunk))))
This is a real example from the A-Lisp compiler. A-Lisp implements
UNWIND-PROTECT by pushing a "thunk" (a function of no arguments) which
performs the cleanup actions onto the catch stack, before executing
the protected form. Since the compiler has to generate code to fiddle
with the "thunk" before it emits the code for the protected form, it
seems perfectly reasonable for it to rearrange the source code. A-Lisp
does in fact use a source-to-source transformation in the first phase of
the compiler to do this.
-Sandra
-------
∂04-Jan-89 0828 CL-Compiler-mailer reminder
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 4 Jan 89 08:28:37 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA22190; Wed, 4 Jan 89 09:27:32 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06657; Wed, 4 Jan 89 09:27:30 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901041627.AA06657@defun.utah.edu>
Date: Wed, 4 Jan 89 09:27:28 MST
Subject: reminder
To: cl-compiler@sail.stanford.edu
I'd like to send out the remainder of our issues that are currently
under discussion to X3J13 this weekend. These will all be labelled as
drafts. If you have some complaints about the writeups or comments
you'd like included in them, please let me know by Friday.
-Sandra
-------
∂04-Jan-89 0944 CL-Compiler-mailer Re: Issue COMPILER-LET-CONFUSION, v3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 4 Jan 89 09:44:39 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA24854; Wed, 4 Jan 89 10:42:44 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06729; Wed, 4 Jan 89 10:42:34 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901041742.AA06729@defun.utah.edu>
Date: Wed, 4 Jan 89 10:42:32 MST
Subject: Re: Issue COMPILER-LET-CONFUSION, v3
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: "Kim A. Barrett" <IIM@ecla.usc.edu>, cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Tue, 3 Jan 89 17:17:17 GMT
> Is there a way to make COMPILER-LET work correctly short of requiring
> that interpreters do a macroexpansion prepass? Right now, I can't use
> COMPILER-LET in portable code because some macroexpansions happen after
> the dynamic extent of the COMPILER-LET bindings has ended.
This issue once included a proposal called CLARIFY-STATUS-QUO, which
stated that COMPILER-LETs should be processed at the same time as macros
are expanded, but didn't require this to happen in a prepass. You could
still get into trouble by doing things like:
(defvar *foo*)
(compiler-let ((*foo* 'compiler-let-value))
(let ((*foo* 'let-value))
(some-macro)))
SOME-MACRO might see different values of *FOO* in different implementations,
depending on whether the interpreter does macroexpansion in parallel with
evaluation or in a prepass.
This proposal was dropped because of lack of support.
-Sandra
-------
∂04-Jan-89 1106 CL-Compiler-mailer Re: Issue COMPILER-LET-CONFUSION, v3
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 4 Jan 89 11:05:38 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA12029; Wed, 4 Jan 89 11:07:07 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA11260; Wed, 4 Jan 89 11:03:43 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA06277; Wed, 4 Jan 89 11:04:46 PST
Date: Wed, 4 Jan 89 11:04:46 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901041904.AA06277@clam.sun.com>
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK, sandra%defun@cs.utah.edu
Subject: Re: Issue COMPILER-LET-CONFUSION, v3
Cc: IIM@ecla.usc.edu, cl-compiler@sail.stanford.edu
> > Is there a way to make COMPILER-LET work correctly short of requiring
> > that interpreters do a macroexpansion prepass? Right now, I can't use
> > COMPILER-LET in portable code because some macroexpansions happen after
> > the dynamic extent of the COMPILER-LET bindings has ended.
>
> This issue once included a proposal called CLARIFY-STATUS-QUO, . . .
Here is an interesting test case for would-be implementations of
compiler-let or something resembling it:
(setq *f*
(compiler-let ((*switch* t))
#'(lambda (x) (my-macro))))
where my-macro's expansion depends on *switch*.
∂04-Jan-89 1125 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 4 Jan 89 11:25:36 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06938; 4 Jan 89 19:03 GMT
Date: Wed, 4 Jan 89 19:07:22 GMT
Message-Id: <1685.8901041907@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
To: sandra <@cs.utah.edu:sandra@defun>, cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Wed, 4 Jan 89 08:59:53 MST
> This is a real example from the A-Lisp compiler.
OK, I think I see the sort of thing you have in mind. But now I
have another question. Even without the explicit provision for
reordering, the compiler or interpreter could rewrite code in various
ways provided that it was impossible (module efficiency) to tell that
it had done so. So what do we gain from the explicit provision?
The key word seems to be "process". The forms might be "processed"
in an arbitrary order. As far as I can tell, the only user-visible
part of processing is macro-expansion. Is that all there is to it,
that the order in which macro calls are expanded is undefined?
∂04-Jan-89 1206 CL-Compiler-mailer Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 4 Jan 89 12:06:38 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA29819; Wed, 4 Jan 89 13:05:26 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06821; Wed, 4 Jan 89 13:05:22 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901042005.AA06821@defun.utah.edu>
Date: Wed, 4 Jan 89 13:05:20 MST
Subject: Re: issue DEFINING-MACROS-NON-TOP-LEVEL, version 6
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: sandra <sandra%defun@cs.utah.edu>, cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Wed, 4 Jan 89 19:07:22 GMT
> Date: Wed, 4 Jan 89 19:07:22 GMT
> From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
>
> Even without the explicit provision for
> reordering, the compiler or interpreter could rewrite code in various
> ways provided that it was impossible (module efficiency) to tell that
> it had done so. So what do we gain from the explicit provision?
This subissue seems to be confusing and nonintuitive to many people,
but after thinking about it for a while most people seem to agree that
it's reasonable. I think it's better to say something explicitly in
the standard instead of just leaving people to be confused.
> The key word seems to be "process". The forms might be "processed"
> in an arbitrary order. As far as I can tell, the only user-visible
> part of processing is macro-expansion. Is that all there is to it,
> that the order in which macro calls are expanded is undefined?
The way I look at it, this part of the proposal does two things:
(1) it says that users can rely on top-level forms in a file being
processed in the order in which they appear.
(2) it leaves the order of processing of non-top-level forms explicitly
vague.
As things stand now, I think macro expansion is indeed the only thing
that users need to be concerned about in the second case. For the first
case, there is also EVAL-WHEN and the handling of compile-time magic
associated with defining macros.
-Sandra
-------
∂04-Jan-89 1351 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 4 Jan 89 13:50:28 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA15830; Wed, 4 Jan 89 13:51:47 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA19676; Wed, 4 Jan 89 13:48:26 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA06604; Wed, 4 Jan 89 13:49:28 PST
Date: Wed, 4 Jan 89 13:49:28 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901042149.AA06604@clam.sun.com>
To: IIM@ECLA.USC.EDU, sandra%defun@cs.utah.edu
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Cc: JonL@LUCID.COM, cl-compiler@SAIL.STANFORD.EDU
An aspect of Common Lisp's EVAL-WHEN has bothered me ever
since the first time I looked at it:
What if I define a macro that expands into an EVAL-WHEN --
suppose I wish to define a macro resembling defmacro,
say def-xxx-macro. Suppose that
(def-xxx-macro gogo (x) ... )
expands into:
(eval-when (compile load eval)
(setf (get 'gogo 'xxx-macro) (function (lambda (x) ... ))))
Now suppose it is something that, like defmacro, only affects
EVALuation and compilation, but my user has an application that
just runs compiled and doesn't need the definition.
I guess my user would like to say:
(eval-when (eval compile)
(def-xxx-macro gogo (x) ... ))
CLtL p.69-70 seems to strongly imply that (if the macro's expansion
counts as a top level form), my user can't turn off the load-time
action of def-xxx-macro.
Exactly the same problem exists if we wish to explain macros such
as DEFMACRO in terms of EVAL-WHEN.
I've always found that I wanted outer EVAL-WHENs to override inner
ones, due to examples such as this. Do others have different experience?
-Cris
∂04-Jan-89 1426 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 4 Jan 89 14:25:33 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA03056; Wed, 4 Jan 89 15:15:19 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA06860; Wed, 4 Jan 89 15:14:06 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901042214.AA06860@defun.utah.edu>
Date: Wed, 4 Jan 89 15:14:05 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: cperdue@Sun.COM (Cris Perdue)
Cc: IIM@ECLA.USC.EDU, sandra%defun@cs.utah.edu, JonL@LUCID.COM,
cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: cperdue@Sun.COM (Cris Perdue), Wed, 4 Jan 89 13:49:28 PST
To simplify your example somewhat, you have something like
(eval-when (eval compile)
(eval-when (compile load eval)
(some-action)))
Your claim is that this still causes (SOME-ACTION) to be performed at
load-time, right? I think you're confused here; unless I'm really
confused myself, neither the definition of EVAL-WHEN in CLtL nor the
definition in the current proposal supports this claim.
According to CLtL p. 70, since the situation COMPILE is specified for
the outer EVAL-WHEN, its body will be evaluated at compile time. But
since the LOAD situation is not specified, the compiler will not
produce any code which causes the body to be evaluated at load time.
When the inner EVAL-WHEN is evaluated at compile time (presumably
using EVAL, although CLtL doesn't say this), it won't produce any code
causing a load-time action even though the LOAD situation is
specified, because it is the interpreter which is doing the processing
at that point, and the interpeter only pays attention to the EVAL
situation.
This aspect of the semantics of EVAL-WHEN is not changed by the current
proposal.
-Sandra
-------
∂04-Jan-89 1657 CL-Compiler-mailer Issue COMPILER-LET-CONFUSION, v3
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 4 Jan 89 16:57:27 PST
Received: from GANG-GANG.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 255959; Wed 4-Jan-89 19:54:36 EST
Date: Wed, 4 Jan 89 19:54 EST
From: Glenn S. Burke <gsb@ALDERAAN.SCRC.Symbolics.COM>
Subject: Issue COMPILER-LET-CONFUSION, v3
To: jonl@lucid.com, IIM@ECLA.USC.EDU
cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: <8901020813.AA21841@bhopal>
Message-ID: <19890105005410.6.GSB@GANG-GANG.SCRC.Symbolics.COM>
Date: Mon, 2 Jan 89 00:13:53 PST
From: Jon L White <jonl@lucid.com>
COMPILER-LET has abundantly been demonstrated to generate immense
confusion in the user community. And the fact that its defenders have
*no* convincing examples where this construct is either critical
or suprememly better than the alternatives means it is simply a
confusing hack. It's rare uses hardly justify its enormous drawback.
Most uses of compiler-let i have seen (and often been responsible for)
have been maintaining a "stack" of data for some macrology to make use
of. That is, it takes the general form
(defmacro with-new-frob (... &body body)
(compiler-let ((*frobs* (cons '(,name . ,data) *frobs*)))
...)
and some other macro or macros reference *frobs*.
It is not obvious to me how to get macrolet to do something similar in a
straightforward and readable fashion.
It is the case that using compiler-let for things like this does not
have the correct behavior, because what I want is something which (1)
follows lexical scoping rules and (2) is available for analysis at
macroexpansion time.
If there were a facility which permitted user code to associate symbols
with data and have this associated with macroexpansion environments and
scoped in the normal lexical fashion, perhaps many of the uses of
compiler-let would be subsumed.
For instance:
(defmacro with-new-frob (... &body body &environment env)
`(macrovar-let ((frobs '((,name . ,data) ,@(macrovar 'frobs env))))
,@body))
MACROVAR-LET is a special form syntactically like COMPILER-LET. Instead of
binding those names to the given values however, the names are
associated with the values in such a way that macros expanded lexically
within the body can access the data by giving MACROVAR arguments of the
name, and their environment argumnet. SETF should work on MACROVAR, but
should be an error if there is no "binding".
I believe CL could use this kind of functionality (perhaps as part of
syntactic-environment-access?). I cannot see flushing compiler-let
unless something like this is provided.
∂04-Jan-89 1841 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 4 Jan 89 18:40:46 PST
Date: Wed 4 Jan 89 14:00:20-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue COMPILER-DIAGNOSTICS, v7
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12459944680.14.IIM@ECLA.USC.EDU>
> Date: Tue, 03 Jan 89 12:53:55 EST
> From: Dan L. Pierson <pierson@mist.encore.com>
>
> ... you need to be able to collect all the things you'd like to turn off as
> subtypes of the same type.
Use (OR ...)
> Date: Tue, 03 Jan 89 13:01:46 EST
> From: Dan L. Pierson <pierson@mist.encore.com>
> > The Lisp Machine has a thing called a notification. I might be
> > susceptible to calling the type a NOTIFICATION and making a function
> > called NOTIFY. Then, at least, there would be current practice behind
> > the idea.
> I have no objection to these name changes.
> I am mildly opposed to the competing proposal because it's redundant with
> mine. I am strongly in favor of one general condition-based mechanism for
> all of these messages.
I agree with Dan. I much prefer the condition-based approach. I much prefer
one general mechanism to spawning an infinite number of keyword arguments with
associated default special variables. It's too bad it doesn't work in all
situations (like GC-MESSAGES), but that doesn't mean we shouldn't use it where
it will work.
kab
-------
∂04-Jan-89 2017 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v7
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 4 Jan 89 20:17:19 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 515575; Wed 4-Jan-89 23:16:10 EST
Date: Wed, 4 Jan 89 23:15 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue COMPILER-DIAGNOSTICS, v7
To: CL-Compiler@SAIL.Stanford.EDU
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <12459944680.14.IIM@ECLA.USC.EDU>
Message-ID: <890104231549.1.KMP@BOBOLINK.SCRC.Symbolics.COM>
btw, i've been thinking more about the lispm's NOTIFY and i'm starting to
feel uncomfortable about using it as a model, and hence about using the
names NOTIFY and NOTIFICATION. at this point, i think whether i'd go along
with those particular names depends on what kind of info it is going to
type out.
The kinds of things people call NOTIFY for on lispm are things like:
GC status: GC needed, GC happening, almost out of room, etc.
Remote file server is going down (or has just come up).
Power in machine room going down.
Some activity (a.k.a. window, process, job, or fork) wants intervention.
Message from another user has arrived.
Note that these are all things which tend not to be associated with the
ongoing activity (compilation, editing, ...) which the user is in at the time
the message is received.
Note also that on the LispM the notification is not dealt with by signalling.
Instead, it is an asynchronous message to the activity. The activity then
decides whether to write on its own window, pop up another window, defer
the notification until later, or whatever.
∂05-Jan-89 1005 CL-Compiler-mailer Re: Compilation implications
Received: from ti.com by SAIL.Stanford.EDU with TCP; 5 Jan 89 10:05:06 PST
Received: by ti.com id AA27755; Thu, 5 Jan 89 12:03:51 CST
Received: from Kelvin by tilde id AA05297; Thu, 5 Jan 89 11:49:50 CST
Message-Id: <2809014625-3421425@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 5 Jan 89 11:50:25 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Jon L White <jonl@lucid.com>
Cc: Common-Lisp-Object-System@Sail.Stanford.edu, CL-Compiler@Sail.Stanford.edu
Subject: Re: Compilation implications
In-Reply-To: Msg of Thu, 29 Dec 88 04:52:47 PST from Jon L White <jonl@lucid.com>
> (A) "Reconstructor" functions for instances
I've been giving this a little thought. I have modified our compiler to
call the generic function RECONSTRUCTION-FORM when it needs to dump an
object that is not one of the primitive types it knows how to handle
directly. It takes the object as its argument and returns a form to be
evaluated to reconstruct the object (or else you get a "no applicable
method" error). With that hook, it then becomes possible to define a
general-purpose object dumper in portable CLOS code, which I hereby donate
to the public domain:
(defclass fasdump-mixin () ()
(:documentation "Including this class allows instances to be dumped to object files."))
(defmacro push-key-and-value (key value list)
`(setf ,list (list* ,key ,value ,list)))
(defmethod reconstruction-form ((object fasdump-mixin))
(let ((plist '())
(class-name (type-of object))
(unbound-slots '())
(allocation-args '()))
(dolist (slot (class-slots (class-of object)))
(let ((name (slot-description-name slot)))
(when (eq (slot-description-allocation slot) ':instance)
(if (slot-boundp object name)
(push-key-and-value name (slot-value object name) plist)
(push name unbound-slots)))))
(if (and (null unbound-slots) (null allocation-args))
`(remake-object ',class-name ',plist)
`(remake-object ',class-name ',plist ',unbound-slots ',allocation-args))))
(defun remake-object (class-name &optional slots-and-values unbound-slots allocation-args)
(let* ((class1 (find-class class-name))
(object (progn (unless (class-finalized-p class1)
(finalize-inheritance class1))
(apply #'allocate-instance class1 allocation-args)))
(class (class-of object))
(deleted-slots '())
(plist '())
(added-slots '())
(default '#,(cons nil nil)))
(do ((tail slots-and-values (cddr tail)))
((atom tail))
(let ((slot-name (first tail)))
(if (slot-exists-p-using-class class object slot-name)
(setf (slot-value-using-class class object slot-name)
(second tail))
(progn (push slot-name deleted-slots)
(push-key-and-value slot-name (second tail) plist)))))
(dolist (slot (class-slots class))
(let ((slot-name (slot-description-name slot)))
(when (and (eq (slot-description-allocation slot) ':instance)
(eq (getf slots-and-values slot-name default) default)
(not (member slot-name unbound-slots :test #'eq)))
(push slot-name added-slots))))
(when (or deleted-slots added-slots)
(update-instance-for-redefined-class object added-slots deleted-slots plist))
object))
Note that this does not require the slots to have initargs, and note the
use of UPDATE-INSTANCE-FOR-REDEFINED-CLASS at the end to take account of
any changes in the class definition between compilation and loading. If
any slot values are themselves class instances, then the compiler will
invoke RECONSTRUCTION-FORM on them in the process of writing out the form
returned by the first call.
While this works, I don't think this is an ideal solution because it
doesn't handle the case of recursive data structures. A better solution
might be something along the lines of having the generic function return
four values:
1. The class name.
2. A list of additional arguments for ALLOCATE-INSTANCE.
3. The name of an initialization function.
4. Initialization arguments.
The loader would then first do
(APPLY #'ALLOCATE-INSTANCE (FIND-CLASS class-name) other-allocate-args)
to create the object before it begins reading the next two items, and then
finally do
(APPLY (SYMBOL-FUNCTION init-function) the-object initialization-args)
to fill in the slots.
> Possibly, EQL specializers could raise this question. Upon re-reading,
> the language of 88-002R now seems a bit vague to me, and possibly open
> to misinterpretation, as to just when an EQL parameter specializer form
> is evaluated.
Yes, I ran into this when I wrote a method that looked something like
this:
(DEFMETHOD MAKE-INSTANCE ((CLASS (EQL (FIND-CLASS 'MY-CLASS))) ...) ...)
which wouldn't work without doing something like this:
(defmethod reconstruction-form ((object class))
(let ((class-name (class-name object)))
(if (and (symbolp class-name)
(eq (find-class class-name nil) object))
`(find-class ',class-name)
(error "Can't dump ~S to object file because it doesn't have a proper name." object))))
but I'm not sure if this is what the designers of CLOS had in mind.
> (B) References to classes "by name"
>
> The analogy between FIND-PACKAGE and FIND-CLASS suggests that class
> objects are in the same "database" category as packages. Shouldn't
> they be referenced "by name" in compiled file?
That sounds right to me.
> I realize this may pose some ordering constraints on the executions in a
> file, if the compiled version is to operate correctly -- i.e., classes might
> have to be defined before the use of any constant that "names" that class.
> Such constraints may not be as feasible as they are in the package world
> (Indeed, some folks even dislike the package ordering constraints!). Can
> a forward-reference, "placeholder" be substituted for a class that hasn't
> yet been defined, but is referenced by a quoted constant?
We ran into this problem where we optimize calls to TYPEP to specialized
code using the class object, which might not be defined yet when the code
is loaded, so at that point the loader constructs a dummy class definition
and trusts it to be redefined correctly later. So far, that seems to be
working ok, but, again, I'm not sure if that is really considered proper.
∂05-Jan-89 1016 CL-Compiler-mailer Re: Issue COMPILER-DIAGNOSTICS, v7
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 5 Jan 89 10:15:50 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA08519; Thu, 5 Jan 89 11:22:44 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA14972; Thu, 5 Jan 89 11:22:45 EST
Message-Id: <8901051622.AA14972@mist.>
To: "Kim A. Barrett" <IIM@ECLA.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU
Subject: Re: Issue COMPILER-DIAGNOSTICS, v7
In-Reply-To: Your message of Wed, 04 Jan 89 14:00:20 -0800.
<12459944680.14.IIM@ECLA.USC.EDU>
Date: Thu, 05 Jan 89 11:22:43 EST
From: Dan L. Pierson <pierson@mist.encore.com>
> Date: Tue, 03 Jan 89 12:53:55 EST
> From: Dan L. Pierson <pierson@mist.encore.com>
>
> ... you need to be able to collect all the things you'd like to
> turn off as subtypes of the same type.
Use (OR ...)
Or (MEMBER ...); the problem is that we're talking portability here
and not all implementations usefully handle OR or MEMBER type
combinations...
∂05-Jan-89 1228 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 5 Jan 89 12:27:52 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA03018; Thu, 5 Jan 89 11:53:54 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA22005; Thu, 5 Jan 89 11:50:15 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA07571; Thu, 5 Jan 89 11:51:17 PST
Date: Thu, 5 Jan 89 11:51:17 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901051951.AA07571@clam.sun.com>
To: sandra%defun@cs.utah.edu
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Cc: IIM@ECLA.USC.EDU, JonL@LUCID.COM, cl-compiler@SAIL.STANFORD.EDU
Sandra has to be right -- I was confused about what my example would
do. Well, I'm not giving up yet. Here is a different example.
Suppose we have code something like:
(eval-when (load)
(eval-when (compile load eval)
(some-action)))
This might come in a form such as:
(eval-when (load)
(def-xxx-macro frob (x) ... ))
where def-xxx-macro expands into an eval-when.
I claim that this case, as described in CLtL, does "some-action" at
compile-time despite the request of the user of def-xxx-macro and
despite appearances. So once again, does anyone know
of reasons why the inner EVAL-WHEN should in effect override
the outer one?
-Cris
∂05-Jan-89 1235 CL-Compiler-mailer Re: Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, v7
Received: from ti.com by SAIL.Stanford.EDU with TCP; 5 Jan 89 12:35:10 PST
Received: by ti.com id AA28310; Thu, 5 Jan 89 14:33:55 CST
Received: from Kelvin by tilde id AA08766; Thu, 5 Jan 89 14:19:30 CST
Message-Id: <2809023621-3961932@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 5 Jan 89 14:20:21 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "Kim A. Barrett" <IIM@ECLA.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU
Subject: Re: Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, v7
In-Reply-To: Msg of Sat 31 Dec 88 19:38:58-PST from Kim A. Barrett <IIM@ECLA.USC.EDU>
> No, the processing of the accessor functions should expand to code which does
> something equivelent to
>
> (progn
> (proclaim '(inline <accessor>))
> (defun <accessor> (structure)
...
> which does not make <accessor> defined at compile time (see DEFUN).
Yes, it could be recorded for inline expansion without making it
executable in the compile time environment, but our implementation uses
the same mechanism for both, so proclaiming it inline also makes it
available to be called at compile-time. The question is whether the
standard intends to say that such an implementation approach is not
valid.
> > DEFCLASS: ... and for use as the :METACLASS option of a subsequent
> > DEFCLASS.
>
> No, because doing so would require that the class be instantiable, so that you
> can make instances whose class is the metaclass, for descrimination purposes.
> That's what having it available as a metaclass is all about. I seem to
> remember somewhere in the CLOS spec the caveat that a class had to be fully
> defined before it could be used as a metaclass argument to defclass, presumably
> for this reason.
It could be fully defined in the compile-time environment. It isn't
clear whether the designers of CLOS intended being able to use a
metaclass in the same file in which it is defined, but the concepts of
anonymous classes and looking up class definitions in the compile-time
environment means that it is certainly possible to instantiate classes
that are defined only in the compile-time environment.
> > The compiler must make the class definition available to be returned by
> > FIND-CLASS when its environment argument is a value received as the
> > &ENVIRONMENT parameter of a macro.
>
> This should perhaps be tightened up a bit. For example, the &environment
> argument should have been generated by the same invocation of the compiler as
> that which processed the defclass.
Yes, I agree that environments should be viewed as having dynamic
extent. I'm not sure, though, whether this proposal is the right place
to say that.
∂05-Jan-89 1302 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 5 Jan 89 13:02:41 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA05433; Thu, 5 Jan 89 14:00:33 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA07387; Thu, 5 Jan 89 14:00:25 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901052100.AA07387@defun.utah.edu>
Date: Thu, 5 Jan 89 14:00:23 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: cperdue@Sun.COM (Cris Perdue)
Cc: IIM@ECLA.USC.EDU, JonL@LUCID.COM, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: cperdue@Sun.COM (Cris Perdue), Thu, 5 Jan 89 11:51:17 PST
> (eval-when (load)
> (eval-when (compile load eval)
> (some-action)))
>
> I claim that this case, as described in CLtL, does "some-action" at
> compile-time despite the request of the user of def-xxx-macro and
> despite appearances. So once again, does anyone know
> of reasons why the inner EVAL-WHEN should in effect override
> the outer one?
I agree that this example behaves the way you describe. As I
understand it, you'd like to see the absence of the COMPILE situation
in an outer EVAL-WHEN prevent compile-time evaluation resulting from
any nested EVAL-WHENs, right?
Interestingly enough, in an earlier message JonL suggested that the
*presence* of the COMPILE situation in an outer EVAL-WHEN should
prevent compile-time evaluation of nested EVAL-WHENs (to prevent
multiple evaluations). This suggests a simple solution that would
address both problems: simply change the definition of "top-level" so
that EVAL-WHEN *never* passes top-level-ness on to its body forms.
Doing this would be an incompatible change from the behavior specified
in CLtL, where wrapping a form in an (EVAL-WHEN (EVAL LOAD)...) is
essentially a no-op. I have rather mixed feelings about this; on the
one hand the behavior you want cannot be expressed using the current
definition and the change does have some appeal because of its
simplicity, but on the other hand it may break some user code.
Anybody else have thoughts on this?
-Sandra
-------
∂05-Jan-89 1344 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 2
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 5 Jan 89 13:43:18 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa07384; 5 Jan 89 20:39 GMT
Date: Thu, 5 Jan 89 20:34:21 GMT
Message-Id: <4019.8901052034@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue QUOTE-MAY-COPY, version 2
To: Cris Perdue <cperdue@sun.com>, sandra <@cs.utah.edu:sandra@defun>
In-Reply-To: Cris Perdue's message of Tue, 3 Jan 89 09:46:22 PST
Cc: KMP@scrc-stony-brook.arpa, cl-compiler@sail.stanford.edu
> > Rather than making an exception for gensyms, I'm inclined to believe
> > that *all* sharing of structures within an expression passed to EVAL,
> > a function passed to COMPILE, or the entire contents of a file
> > compiled with COMPILE-FILE ought to be preserved. I don't think it
> > would be unreasonable for your first example to return NIL, but I
> > think the second one ought to return true (regardless of whether the
> > value of A is a gensym or some other kind of object).
I don't see how that is consistent with allowing QUOTE to copy.
> > This really falls under issue CONSTANT-CIRCULAR-COMPILATION . . .
I think all of these issues are closely related, because they all
involve moving file compilation semantics into the rest of the
langauge. My gensym example was to say that if the EQL relationships
of uninterned symbols change across file compilations, and if we adopt
the file compilation semantics for constants in general, then the EQL
realtionships of uninterned symbols can never be guaranteed (except
where they appear in code).
∂05-Jan-89 1336 Common-Lisp-Object-System-mailer Re: Compilation implications
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Jan 89 13:35:47 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 516094; Thu 5-Jan-89 16:32:43 EST
Date: Thu, 5 Jan 89 16:32 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Compilation implications
To: David N Gray <Gray@DSG.csc.ti.com>
cc: Jon L White <jonl@lucid.com>, Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu
In-Reply-To: <2809014625-3421425@Kelvin>
Message-ID: <19890105213202.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 5 Jan 89 11:50:25 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> Possibly, EQL specializers could raise this question. Upon re-reading,
> the language of 88-002R now seems a bit vague to me, and possibly open
> to misinterpretation, as to just when an EQL parameter specializer form
> is evaluated.
Yes, I ran into this when I wrote a method that looked something like
this:
(DEFMETHOD MAKE-INSTANCE ((CLASS (EQL (FIND-CLASS 'MY-CLASS))) ...) ...)
which wouldn't work without doing something like this:
(defmethod reconstruction-form ((object class))
(let ((class-name (class-name object)))
(if (and (symbolp class-name)
(eq (find-class class-name nil) object))
`(find-class ',class-name)
(error "Can't dump ~S to object file because it doesn't have a proper name." object))))
but I'm not sure if this is what the designers of CLOS had in mind.
The macroexpansion of defmethod must be wrong. The form inside the EQL
parameter specializer name should be evaluated at load time, not at
compile time. That's my opinion anyway; 88-002R doesn't say as far as
I can see.
∂05-Jan-89 1342 Common-Lisp-Object-System-mailer Re: Compilation implications
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Jan 89 13:42:11 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 516101; Thu 5-Jan-89 16:39:43 EST
Date: Thu, 5 Jan 89 16:39 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Compilation implications
To: David N Gray <Gray@DSG.csc.ti.com>
cc: Jon L White <jonl@lucid.com>, Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu
In-Reply-To: <2809014625-3421425@Kelvin>
Message-ID: <19890105213908.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 5 Jan 89 11:50:25 CST
From: David N Gray <Gray@DSG.csc.ti.com>
(defclass fasdump-mixin ....
While this works,
For classes where simply saving the values of the slots is enough to save
all relevant state of the object, and where simply restoring equivalent
values into the slots and not calling make-instance, initialize-instance,
nor shared-initialize is enough to create an equivalent object. Such
classes do exist, so this is worth telling people how to do so they can
use it with such classes.
I don't think this is an ideal solution because it
doesn't handle the case of recursive data structures. A better solution
might be something along the lines of having the generic function return
four values:
1. The class name.
2. A list of additional arguments for ALLOCATE-INSTANCE.
3. The name of an initialization function.
4. Initialization arguments.
The loader would then first do
(APPLY #'ALLOCATE-INSTANCE (FIND-CLASS class-name) other-allocate-args)
to create the object before it begins reading the next two items, and then
finally do
(APPLY (SYMBOL-FUNCTION init-function) the-object initialization-args)
to fill in the slots.
You can make your REMAKE-OBJECT technique do this without modifying the loader
(you have to put in a special variable that allows you to detect recursive
calls). Or did you want to do the final step at some later time than when
the outermost in a set of nested objects is created? I don't think deferring
the final step until the end of loading the file would work in many cases.
∂05-Jan-89 1448 CL-Compiler-mailer Re: issue CONSTANT-COLLAPSING, version 3
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 5 Jan 89 14:46:59 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08082; 5 Jan 89 22:37 GMT
Date: Thu, 5 Jan 89 22:32:49 GMT
Message-Id: <4075.8901052232@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue CONSTANT-COLLAPSING, version 3
To: sandra <@cs.utah.edu:sandra@defun>, cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Tue, 3 Jan 89 14:02:35 MST
> Cost to users:
>
> It is hard to imagine a program that would break under this proposal.
> The EQL-ness or uniqueness of composite structures in compiled code
> cannot be guaranteed in any event, since the combination of
> COMPILE-FILE and LOAD generally results in a copy of the original
> structure.
Elsewhere, you seem to think EQL-ness within a given COMPILE-FILE
can be preserved:
From: sandra <(Sandra J Loosemore)sandra%defun@edu.utah.cs>
Date: Sat, 31 Dec 88 14:59:59 MST
Subject: Re: issue QUOTE-MAY-COPY, version 2
Rather than making an exception for gensyms, I'm inclined to believe
that *all* sharing of structures within an expression passed to EVAL,
a function passed to COMPILE, or the entire contents of a file
compiled with COMPILE-FILE ought to be preserved.
-- Jeff
∂05-Jan-89 1451 CL-Compiler-mailer Re: Compilation implications
Received: from ti.com by SAIL.Stanford.EDU with TCP; 5 Jan 89 14:50:58 PST
Received: by ti.com id AA29024; Thu, 5 Jan 89 16:49:03 CST
Received: from Kelvin by tilde id AA11935; Thu, 5 Jan 89 16:40:27 CST
Message-Id: <2809032076-4469910@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 5 Jan 89 16:41:16 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Jon L White <jonl@lucid.com>, Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu
Subject: Re: Compilation implications
In-Reply-To: Msg of Thu, 5 Jan 89 16:39 EST from David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
> You can make your REMAKE-OBJECT technique do this without modifying the loader
> (you have to put in a special variable that allows you to detect recursive
> calls).
The problem with the approach of reading one form and then evaluating it
is that the slot values have already been read and constructed before
allocating the object they go in. I suppose it would be possible to add
special handling for recursive references that would maintain a list of
these so that the loader can go back and fill them in later, but the
approach of allocating the object before reading its contents is much
simpler. That's what we already do for lists and arrays.
∂05-Jan-89 1526 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 5 Jan 89 15:22:41 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08421; 5 Jan 89 23:17 GMT
Date: Thu, 5 Jan 89 23:12:06 GMT
Message-Id: <4093.8901052312@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: sandra <@cs.utah.edu:sandra@defun>, cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Tue, 3 Jan 89 13:54:56 MST
> The proposals below apply to COMPILE-FILE, since it must inherently
> copy structures. If issue QUOTE-MAY-COPY is resolved in favor of
> allowing COMPILE and possibly EVAL to copy structures, the same
> constraints would also apply in those situations.
Since these are not independent issues, I am not sure how to arrange
a fair vote. My vote on either issue might depend on which version
of the other issue passed. Is there a known procedure for dealing
with such problems?
> Proposal CONSTANT-CIRCULAR-COMPILATION:NO
>
> State that it is an error for an object containing a circular reference to
> appear as a constant to be compiled. State that the compiler is not
> required to preserve EQness of substructures.
Do you mean EQLness?
What does "preserve EQness" mean? Does it mean things don't get less
EQ (copying), don't get more EQ (coalescing), or both? I suspect it means
don't get less EQ, but see below.
> Proposal CONSTANT-CIRCULAR-COMPILATION:PRESERVE-SHARING-ONLY
>
> State that it is an error for an object containing a circular
> reference to appear as a constant to be compiled. State that the
> compiler is required to preserve EQness of substructures within a file
> compiled with COMPILE-FILE.
>
> Rationale:
>
> Disallowing portable programs from containing circular constants
> allows compiled file loaders to use somewhat simpler implementation
> strategies (for example, to build constants in a strict bottom-up
> fashion).
>
> Some programs (such as PCL) have come to depend on COMPILE-FILE
> preserving the EQness of uninterned symbols, and it is cleaner
> to requiring sharing to be preserved in general instead of making
↑ require?
> symbols be a special case. Requiring sharing to be preserved still
> allows loaders to build constants bottom-up.
> [...]
Symbols are always going to be a special case because after a dump and
load we can usually expect to get the same symbol back while we do not
expect this for conses. And we often want uninterned symbols to be as
much as possible like other symbols except that they don't conflict
if their names happen to be the same. Therefore, I think it is
reasonable to expect different things from uninterned symbols than
from conses in file compilations.
It also seems to me that if symbols are supposed to stay EQ when they're
EQ they should also stay non-EQ when they're non-EQ. Then, if we want
symbols not to be a special case, conses also have to stay non-EQ when
they're not EQ, and we can't have coalescing. So it again looks like
we might want symbols to be a special case. But maybe not. Maybe
coalescing is the problem.
I am still not sure we have a reasonable account of compilation and
constants that answers all of the different questions about copying,
coalescing, the implications for COMPILE and EVAL, etc. in a way that
makes sense.
> Current Practice:
>
> A-Lisp preserves EQness of substructures (since it makes an effort to
> collapse isomorphic structures) but signals an error if an attempt is
> made to compile a circular constant.
Suppose I had an implementation that coalesced uninterned symbols that
had the same print name. Would that be preserving EQness?
> Discussion:
>
> JonL has argued against proposal CONSTANT-CIRCULAR-COMPILATION:NO, saying
>
> I don't see any performance justification; and even if there were, I'd
> look at it with a very jaundiced eye, favoring interpreter/compiler
> consistency over nickle-and-dime issues of compiler speed.
As far as circularities are concerned, we could just say they're
illegal in interpreted code too. So I don't think this is an argument
against NO in particular.
Isn't that the way this consistency works in general: specify the
language so that only the file compilation semantics are guaranteed
anywhere?
Yours in confusion,
Jeff
∂05-Jan-89 1550 CL-Compiler-mailer Re: issue QUOTE-MAY-COPY, version 3
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 5 Jan 89 15:49:49 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08453; 5 Jan 89 23:27 GMT
Date: Thu, 5 Jan 89 23:22:06 GMT
Message-Id: <4104.8901052322@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue QUOTE-MAY-COPY, version 3
To: Jon L White <@sail.stanford.edu:jonl@lucid.com>, cperdue@sun.com
In-Reply-To: Jon L White's message of Tue, 3 Jan 89 15:04:29 PST
Cc: cl-compiler@sail.stanford.edu
> re: To say that QUOTE copies in existing implementations is to
> imply that a lot of copying might happen that never actually
> happens. COMPILE-FILE followed by LOAD effectively copies,
> and in KCL, COMPILE effectively makes a copy, but not QUOTE.
>
> This may be repeating previous points, but we've been maintaing that
> the phrase "QUOTE copies" does *not* mean that the function QUOTE
> does any work -- merely that the semantics of "quoted objects" is such
> that you cannot tell whether you got the "original" or some copy
> thereof.
[Or, rather, that any code that relies on the difference is in error.
You can, of course, tell, if you constructed the QUOTE form.]
I think I tried to make a point similar to Chris's. I asked whether
any inplementation copied in interpreted code. My recollection is
that the proposal claimed that disallowing copying in interpreted
code was inconsistent with current practice.
But anyway, if this issue is causing so much confusion, the proposal
should be reworded in a "semantics of quoted objects" way and not
left in "QUOTE may copy" style.
-- Jeff
∂05-Jan-89 1547 Common-Lisp-Object-System-mailer Re: Compilation implications
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Jan 89 15:47:11 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 516198; Thu 5-Jan-89 18:44:15 EST
Date: Thu, 5 Jan 89 18:43 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Compilation implications
To: David N Gray <Gray@DSG.csc.ti.com>
cc: Jon L White <jonl@lucid.com>, Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu
In-Reply-To: <2809032076-4469910@Kelvin>
Message-ID: <19890105234343.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 5 Jan 89 16:41:16 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> You can make your REMAKE-OBJECT technique do this without modifying the loader
> (you have to put in a special variable that allows you to detect recursive
> calls).
The problem with the approach of reading one form and then evaluating it
is that the slot values have already been read and constructed before
allocating the object they go in. I suppose it would be possible to add
special handling for recursive references that would maintain a list of
these so that the loader can go back and fill them in later, but the
approach of allocating the object before reading its contents is much
simpler. That's what we already do for lists and arrays.
Apparently my message wasn't clear. What I meant to say was that you can
make the form returned by your MAKE-LOAD-FORM method do just that, allocate
the object and then fill in its contents. Then you can detect nested
objects and move all the allocation forms to the front.
Oh, I'm sorry. This all depends on the assumption that when the form is
(PROGN form1 form2), the loader evaluates form1 before reading form2. I
had not realized that that might not be true of all loaders. Should we
make special-case treatment of PROGN a requirement?
Probably it would be a better idea for MAKE-LOAD-FORM to return two
values, where the first value is a form that will create the object and
the second value is a form that will further initialize the object?
This way the order of evaluation requirement is more explicit. It's
upward compatible since the second value can be NIL if you don't need
it. Also this gives the opportunity to communicate between the forms
without using a special variable; suppose we plug the object returned by
the first form into the second form and do (schematically):
;; This part happens at compile time
(MULTIPLE-VALUE-BIND (form1.1 form1.2)
(MAKE-LOAD-FORM object1)
(MULTIPLE-VALUE-BIND (form2.1 form2.2)
(MAKE-LOAD-FORM object2)
;; This part happens at load time
(LET ((x1 (EVAL form1.1))
(x2 (EVAL form2.1)))
(WHEN form1.2
(EVAL (APPEND form1.2 (LIST (LIST 'QUOTE x1)))))
(WHEN form2.2
(EVAL (APPEND form2.2 (LIST (LIST 'QUOTE x2))))))))
Should I evolve the proposal I sent out the other day along these lines?
It's still the case that only the programmer of the class knows whether
this is an appropriate protocol, so it has to be under the control of the
programmer, not built-in. Consider, for example, any class whose objects
are interned. Calling ALLOCATE-INSTANCE unconditionally is not going to
work. That's why I prefer to see an interface in terms of forms rather
than in terms of functions, since forms are the simplest way to do
something that is completely general.
∂05-Jan-89 1613 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 5 Jan 89 16:13:16 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA13754; Thu, 5 Jan 89 17:12:09 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA07600; Thu, 5 Jan 89 17:12:06 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901060012.AA07600@defun.utah.edu>
Date: Thu, 5 Jan 89 17:12:05 MST
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: sandra <sandra%defun@cs.utah.edu>, cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Thu, 5 Jan 89 23:12:06 GMT
Thanks for your comments. I'll try to clarify the wording of the
proposal to make it more obvious what "preserving EQness" is supposed
to mean.
On the specific problems with uninterned symbols, I believe this is
really a problem with issue CONSTANT-COMPILABLE-TYPES. It's not really
clear whether it requires non-EQ uninterned symbols in the source code
to remain non-EQ in the compiled code.
I agree that it is confusing to have the problems relating to compiled
constants broken up over several issues. I'm hoping that when these
are presented at the upcoming meeting it will provoke some additional
discussion and we can perhaps get a feel for what the majority view is
on each of the subissues, or work out some compromise positions, that
would allow us to present a more unified view when it comes time for
an actual vote. (I found that the straw votes we took at the last
meeting were very useful in telling us how to proceed on certain
issues.) Anyway, as I see it, people would still argue about all the
subissues individually even if we presented a single mega-proposal
including all of them, and we don't really have a mechanism to have
multiple alternatives for sub-parts of a proposal, either.
-Sandra
-------
∂05-Jan-89 1721 CL-Compiler-mailer Re: Compilation implications
Received: from ti.com by SAIL.Stanford.EDU with TCP; 5 Jan 89 17:20:51 PST
Received: by ti.com id AA29934; Thu, 5 Jan 89 19:19:00 CST
Received: from Kelvin by tilde id AA15060; Thu, 5 Jan 89 19:05:11 CST
Message-Id: <2809040762-4991819@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 5 Jan 89 19:06:02 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Jon L White <jonl@lucid.com>, Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu
Subject: Re: Compilation implications
In-Reply-To: Msg of Thu, 5 Jan 89 18:43 EST from David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
> Probably it would be a better idea for MAKE-LOAD-FORM to return two
> values, where the first value is a form that will create the object and
> the second value is a form that will further initialize the object?
> This way the order of evaluation requirement is more explicit. It's
> upward compatible since the second value can be NIL if you don't need
> it.
Yes, that sounds good except for the problem of how to pass the object to
the second form.
> ... suppose we plug the object returned by
> the first form into the second form and do (schematically):
...
> (WHEN form1.2
> (EVAL (APPEND form1.2 (LIST (LIST 'QUOTE x1)))))
...
This reduces generality because the second form can't use optional
arguments, and it seems a little strange to say that the second value is a
form minus its last argument. I wonder if it wouldn't look nicer to just
designate a variable name to indicate where the object is to be plugged in?
For example, we might do:
(defmethod make-load-form ((object my-class))
(values `(allocate-mine ...)
`(init-mine * ...)))
where it is understood that the loader will bind * to the result of the
first form while evaluating the second. This follows the convention that
* is the result of the previous evaluation, so doesn't introduce a new
name to remember. Now that I think about it, I like this better than my
previous 4-value suggestion.
> Should I evolve the proposal I sent out the other day along these lines?
Yes, I would like to see that.
∂05-Jan-89 2051 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 5 Jan 89 20:51:52 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA06712g; Thu, 5 Jan 89 20:47:42 PST
Received: by bhopal id AA07085g; Thu, 5 Jan 89 20:49:52 PST
Date: Thu, 5 Jan 89 20:49:52 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901060449.AA07085@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cperdue@Sun.COM, IIM@ECLA.USC.EDU, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Sandra J Loosemore's message of Thu, 5 Jan 89 14:00:23 MST <8901052100.AA07387@defun.utah.edu>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Cris's latest example well illustrates why I suggested that the notion of
"toplevel" may not by itself be enough to resolve the EVAL-WHEN semantics.
In particular, I am quite convinced that evaluating a form twice simply
because it is doubly nested in EVAL-WHENs is wrong; certainly for every
other purpose, EVAL-WHEN must "pass back" toplevel-ness.
The macro version of EVAL-WHEN we produced six months or so ago caused
the inner eval whens to be processed slightly differently, by virtue of
locally macroletting the definition of EVAL-WHEN itself. Since you wrote
some of that code, I'm surprised at your recent "retching" at the idea.
-- JonL --
∂06-Jan-89 0749 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 6 Jan 89 07:49:39 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA12266; Fri, 6 Jan 89 08:47:13 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA07944; Fri, 6 Jan 89 08:47:04 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901061547.AA07944@defun.utah.edu>
Date: Fri, 6 Jan 89 08:47:02 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: Jon L White <jonl@lucid.com>
Cc: sandra%defun@cs.utah.edu, cperdue@Sun.COM, IIM@ECLA.USC.EDU,
cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Jon L White <jonl@lucid.com>, Thu, 5 Jan 89 20:49:52 PST
My earlier "retching" was at the prospect of having EVAL-WHEN use
different rules for deciding when to perform compile-time side-effects
than all of the various defining macros. I don't think we want to
rule out the use of EVAL-WHEN for implementing those side-effects. On
the other hand, a few people (notably Pitman) have been quite
insistent that we do not *require* EVAL-WHEN to be used to implement
those side-effects (it ought to be legal for the compiler to treat the
defining macros as "special forms" when they appear at top-level).
That is why I think changing the meaning of "top-level" is the
cleanest solution to the problem. If you agree with me that EVAL-WHEN
and the defining macros should use the same rules for deciding when to
do compile-time side-effects, then the only other consequence of
top-level-ness is the order of processing issue. At least in the
(COMPILE LOAD) case, I don't think this ought to cause much of a
problem. Alternatively, if we have to make an exception somewhere, it
seems like this is the place to make it: say that the bodies of
EVAL-WHENs are not top-level (at least in the (COMPILE LOAD) case) but
the compiler has to process them in order anyway.
-Sandra
-------
∂06-Jan-89 0934 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 6 Jan 89 09:33:55 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA19948; Fri, 6 Jan 89 09:35:23 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA21810; Fri, 6 Jan 89 09:31:49 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA08776; Fri, 6 Jan 89 09:32:44 PST
Date: Fri, 6 Jan 89 09:32:44 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901061732.AA08776@clam.sun.com>
To: jonl@lucid.com, sandra%defun@cs.utah.edu
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Cc: IIM@ECLA.USC.EDU, cl-compiler@SAIL.STANFORD.EDU
Put me in the same camp with Sandra on this idea of making
the bodies of EVAL-WHEN forms *not* top level. It looks like
it will contribute to the simplest sensible specification
of EVAL-WHEN.
Again, if anyone knows of reasons why inner EVAL-WHEN's should
override outer ones, it would be very valuable to let us know.
-Cris
∂06-Jan-89 1231 CL-Compiler-mailer Re: issue COMPILE-ARGUMENT-PROBLEMS
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 6 Jan 89 12:29:19 PST
Received: from mist.encore.COM by multimax.encore.com (5.59/25-eef)
id AA21500; Fri, 6 Jan 89 15:25:59 EST
Received: from localhost by mist. (4.0/SMI-4.0)
id AA15869; Fri, 6 Jan 89 15:26:02 EST
Message-Id: <8901062026.AA15869@mist.>
To: "sandra%defun@cs.utah.edu"@multimax.encore.com (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue COMPILE-ARGUMENT-PROBLEMS
In-Reply-To: Your message of Mon, 02 Jan 89 23:08:30 -0700.
<8901030608.AA05391@defun.utah.edu>
Date: Fri, 06 Jan 89 15:25:56 EST
From: Dan L. Pierson <pierson@mist.encore.com>
I would much rather do that than re-open
the issue (I think our time would be better spent trying to deal with
the many other unresolved issues we still have pending), but if you
feel strongly about this then of course we can go ahead and ask for
another vote.
I don't think the cost of reopening this needs be too great if we do
it right.
A problem I have with your proposal is that I believe that
COMPILED-FUNCTION-P must be true of any function returned from
COMPILE,
As Kent said, an interpreted-only system could make
COMPILED-FUNCTION-P true of every function.
and that COMPILE must also at least ensure that all macro
calls in the function have been expanded. I don't think that allowing
COMPILE to do nothing when passed an interpreted function is a
legitimate option.
While I think that this is good guidance, I'm not sure that it has to
be in the standard. Since Common Lisp interpreters are still legal, I
don't see how a COMPILE that did absolutely nothing to an interpreted
function would break anything (other than some implementors' sense of
taste :-)).
More importantly, I see Kent's point that blindly compiling every
symbol in a package that is FBOUNDP should be safe as critical. The
ability for both users and programs to use incremental compilation to
speed things up a tremendously valuable facility that we should do
everything in our power to encourage.
I've actually been trying to draft a short document for Kathy Chapman
to describe the minimum functionality required for implementations of
COMPILE and COMPILE-FILE (incorporating Steve's famous "compiler
model" from last March), but if what's obvious to me isn't obvious to
other people, I should probably turn at least this one part of the
writeup into a new issue so we can vote on it formally.
I certainly thing that this committee should have a change to review
such a document.
∂06-Jan-89 1502 CL-Compiler-mailer Re: issue COMPILE-ENVIRONMENT-CONSISTENCY
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:02:43 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 05 JAN 89 21:27:51 PST
Date: 5 Jan 89 21:27 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue COMPILE-ENVIRONMENT-CONSISTENCY
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Tue, 3 Jan 89 15:24:49 MST
To: cl-compiler@sail.stanford.edu
cc: masinter.pa@Xerox.COM
Message-ID: <890105-212751-184@Xerox>
This proposal is written in the operational terms of what "a compiler" can
"wire in" or otherwise "assume". Is a program that only operates correctly
if the compiler doesn't "assume" these things legal? Conform to the
standard?
We've are defining the language in terms of what conformal programs will
do, and how conformal implementations will behave, almost completely
independent of the compile/interpret aspect -- rightfully so.
Most of the things that you say the "compile can assume" are in fact
constraints on valid programs.
For example
"The compiler may assume that functions that are defined and
declared INLINE in the compiletime environment will retain the same
definitions at runtime."
really means is that when calling a function that was originally defined
and declared INLINE but, at some later point in time, redefined, the
results are unspecified in that either the old (INLINE-proclaimed) or new
definition might be invoked.
I'm just worried about the process of going from this proposal to what
actually has to happen in the standard document.
We had considerable debate about 2b (I think on the common lisp mailing
list.) 2d is subsumed by cleanup LISP-SYMBOL-REDEFINITION, is it not?
2f means that you can't change a DEFCONSTANT, doesn't it?
∂06-Jan-89 1503 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:02:58 PST
Received: from Semillon.ms by ArpaGateway.ms ; 05 JAN 89 21:42:03 PST
Date: 5 Jan 89 21:41 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue LOAD-TIME-EVAL
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Tue, 3 Jan 89 15:28:30 MST
To: cl-compiler@sail.stanford.edu
cc: masinter.pa@Xerox.COM
Message-ID: <890105-214203-187@Xerox>
I don't think (CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
is a good example; you'd do better to say, e.g.,
(defmacro cons-self (x) `(cons ,x ,x))
(cons-self (load-time-value (compute-it)))
the macro expansion of load-time-value might contain EQ structures. This is
a pretty subtle point that really has to do with macro-expansion-caching --
you'd be better off explaining what you're outlawing here.
∂06-Jan-89 1502 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:02:36 PST
Received: from Semillon.ms by ArpaGateway.ms ; 05 JAN 89 20:57:48 PST
Date: 5 Jan 89 20:57 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue ALLOW-LOCAL-INLINE
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Tue, 3 Jan 89 15:23:02 MST
To: cl-compiler@sail.stanford.edu
cc: masinter.pa@Xerox.COM
Message-ID: <890105-205748-182@Xerox>
I don't like this at all. I'd prefer to see compilers sweat to
automatically go back and grab the definition if you say
(declare (inline frobnicate))
somewhere way after frobnicate was defined.
That is
"Local INLINE declarations are of little use without some way of
alerting the compiler to the possibility of inline expansion before
the function is compiled."
isn't really true if compilers worked harder.
However, as you say, this reflects current practice. I think I'd like the
ALLOW-INLINE proclaimation instead.
That is, of the multiple levels of control
* always inline
* maybe inline (let the compiler decide)
* just save the definition for possible local inline
* default
* never inline
I don't see a need for distinguishing between
* always inline
and
* maybe inline (let the compiler decide)
since "always inline" really means "let the compiler decide" anyway. The
control over the compilers heuristics are more portably controlled via the
SPACE vs SPEED parameters, are they not?
I also don't see a need for distinguishing between "default" and "never
inline", since the default *is* never inline, is it not?
This leaves us with three possibilities: INLINE, NOTINLINE and
ALLOW-INLINE.
∂06-Jan-89 1502 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:02:48 PST
Received: from Semillon.ms by ArpaGateway.ms ; 05 JAN 89 21:34:21 PST
Date: 5 Jan 89 21:33 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue SHARP-COMMA-CONFUSION
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Tue, 3 Jan 89 15:30:43 MST
To: cl-compiler@sail.stanford.edu
cc: masinter.pa@Xerox.COM
Message-ID: <890105-213421-186@Xerox>
Actually, I think this is bogus. The simple portable way to handle #, is to
have the compiler use a a readtable which has ' defined as a readmacro like
` but which looks for #, instead of , and then wraps LOAD-TIME-EVAL around
the #,'d forms.
e.g., if
`(a b ,c) reads as (internal:backquote (a b (internal:comma c)))
then
'(a b #,c) reads as (internal:load-time-quote (a b (internal:load-time-eval
c))
only in the compiler's read macro.
Normally, #, has the same read behavior as #. so program-analyzing programs
wont even see it.
I wouldn't mind getting rid of #., #, and #+ and #-, since they *all* have
the problem that program analyzing programs don't see them. However, I see
little point of removing one without getting rid of the rest of 'em, too.
∂06-Jan-89 1504 CL-Compiler-mailer issue LOAD-TIME-EVAL
Received: from moon.src.honeywell.com (ALTURA.HONEYWELL.COM) by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:03:46 PST
Return-Path: <alarson@src.honeywell.com>
Received: from pavo.SRC.Honeywell.COM
by moon.src.honeywell.com (5.59/smail2.6.3/06-17-88)
id AA00812; Fri, 6 Jan 89 17:02:18 CST
Posted-Date: Fri, 6 Jan 89 17:00:45 CST
Received: by pavo.src.honeywell.com (3.2/SMI-3.2)
id AA12249; Fri, 6 Jan 89 17:00:45 CST
Date: Fri, 6 Jan 89 17:00:45 CST
From: alarson@src.honeywell.com (Aaron Larson)
Message-Id: <8901062300.AA12249@pavo.src.honeywell.com>
To: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Tue, 3 Jan 89 15:28:30 MST <8901032228.AA06041@defun.utah.edu>
Subject: issue LOAD-TIME-EVAL
I'm somewhat perplexed by the following paragraph:
Implementations must guarantee that each reference to a
LOAD-TIME-VALUE expression results in at least one evaluation of its
nested <form>. For example,
(CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
must perform two calls to COMPUTE-IT; although there is only one
unique LOAD-TIME-VALUE expression, there are two distinct references
to it.
I believe I understand the question being addressed, but I've never seen
anything in CLtL addressing the issue of shared list structure in evaluable
code, i.e. does'n (EQ #1=(CONS 'A 'B) #1#) return NIL? What would permit
the compiler of LOAD-TIME-VALUE to colapse the two calls? Is this intended
to distinguish LOAD-TIME-VALUE from QUOTE (ref: (EQ '(A) '(A)) => ??)? I
was under the impression that the only loophole permitting the compiler to
copy/substitute otherwise non EQ forms was with regard to QUOTE. Is:
(EQ (LOAD-TIME-EVAL '(A)) (LOAD-TIME-EVAL '(A)))
permitted to return T because of the quoted structure, or required to
return NIL because of the statement about EVALing the form twice?
∂06-Jan-89 1528 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:28:33 PST
Received: from relay2.cs.net by RELAY.CS.NET id ag06590; 6 Jan 89 9:05 EST
Received: from draper.com by RELAY.CS.NET id ab27590; 6 Jan 89 8:38 EST
Date: Fri, 6 Jan 89 08:15 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER,SEB1525
I think it would be a VERY BAD IDEA to have EVAL-WHEN "not pass top-level-ness"
on to its forms. Yes, that would break user code - it would break existing
macros (including lots of system-defined things like DEFSTRUCT if they
weren't majorly changed), and how would you rewrite these things to make them
work in such a world?
Many common uses of EVAL-WHEN would have different behavior. e.g.:
(eval-when (compile load eval)
(proclaim '(special foo)) ; make FOO special to compiler and in compiled code
(defun some-function (...) ...) ; make a function definition available, etc.
(define-setf-method ...) ; you get the idea by now...
...
)
If we are to be sensitive to top-level-ness, as the direction seems to be,
then taking top-level-ness away in such a common situation after we have
established unique behavior for certain forms at top level would be a
grave mistake.
∂06-Jan-89 1535 CL-Compiler-mailer QUOTE and compiled/interpreted consistency
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:30:14 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa07459; 6 Jan 89 22:42 GMT
Date: Fri, 6 Jan 89 22:38:01 GMT
Message-Id: <6349.8901062238@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: QUOTE and compiled/interpreted consistency
To: cl-compiler@sail.stanford.edu
What seems to be happening is that we have several issues about
how the file compiler treats constants and one (QUOTE-MAY-COPY)
that says whether these things apply to interpreted and COMPILE'd
code too. For example:
Issue: CONSTANT-CIRCULAR-COMPILATION (v4)
Problem Description:
[...]
The proposals below apply to COMPILE-FILE, since it must inherently
copy structures. If issue QUOTE-MAY-COPY is resolved in favor of
allowing COMPILE and possibly EVAL to copy structures, the same
constraints would also apply in those situations.
This means that it is difficult to vote on these issues in isolation,
and I'm worried that the results might not fit together very well.
Some people have argued for QUOTE-MAY-COPY:ALWAYS on the grounds that
it advances the cause of consistency between interpreted and compiled
code. But there are a large number of issues involved there, and not
just the ones involving QUOTE. For exmaple:
COMPILER-LET works when code is compiled, because it's body is also
fully macroexopanded during the extent of the COMPILER-LET, but runs
into problems in interpreted code because the body might not be
fully expanded until later on.
LOAD-TIME-EVAL can be used to return an object that can then be
modified. It therefore supplies "static data". But in interpreted
code it might return a new object each time, if for no other reason
than because repeated macroexpansion might keep making new LOAD-TIME-
EVAL forms.
Now, if LOAD-TIME-EVAL worked in interpreted code (by which I mean were
guaranteed to return the same object each time), then there would be less
reason to want QUOTE to preserve EQL realationships. So here again the
issues are related. Actually, if you look at LOAD-TIME-VALUE(8), the true
situation is even worse: it's interpreted semantics are explicitly made
equivalent to something involving QUOTE; so it might turn out that it
couldn't return circular objects or ones that couldn't be dumped!
I submit that this situation is unreasonable and that we should try
to at least suggest a consistent view (rather than simply present all
the different issues).
-- Jeff
∂06-Jan-89 1536 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:35:52 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06055; Fri, 6 Jan 89 16:34:38 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA08280; Fri, 6 Jan 89 16:33:50 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901062333.AA08280@defun.utah.edu>
Date: Fri, 6 Jan 89 16:33:48 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: "Steve Bacher (Batchman)" <SEB1525@draper.com>, Fri, 6 Jan 89 08:15 EST
> Many common uses of EVAL-WHEN would have different behavior. e.g.:
> (eval-when (compile load eval)
> (proclaim '(special foo)) ; make FOO special to compiler and in compiled code
> (defun some-function (...) ...) ; make a function definition available, etc.
> (define-setf-method ...) ; you get the idea by now...
> ...
> )
Ummm, I'm not sure how taking away the top-level-ness of the body of
the EVAL-WHEN would change the behavior of this example. Since the
COMPILE situation causes the body to be evaluated as an explicit PROGN
*before* any other normal compiler processing of the body, the
PROCLAIM will still get evaluated at compile time, SOME-FUNCTION will
be defined in at compile time, and the DEFINE-SETF-METHOD will be
defined at compile time. Can you please clarify why you think this
example would break?
-Sandra
-------
∂06-Jan-89 1520 Common-Lisp-Object-System-mailer Compilation implications
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:18:46 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA27087; Fri, 6 Jan 89 15:19:58 PST
Received: from lukasiewicz.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA07702; Fri, 6 Jan 89 15:16:36 PST
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA00547; Fri, 6 Jan 89 15:19:04 PST
Date: Fri, 6 Jan 89 15:19:04 PST
From: jrose@Sun.COM (John Rose)
Message-Id: <8901062319.AA00547@lukasiewicz.sun.com>
To: jonl@lucid.com
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM,
Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu
In-Reply-To: Jon L White's message of Fri, 30 Dec 88 03:46:40 PST <8812301146.AA13748@bhopal>
Subject: Compilation implications
Date: Fri, 30 Dec 88 03:46:40 PST
From: Jon L White <jonl@lucid.com>
Thanks for your many comments, Dave. I'm sure they will be useful.
re: ["Reconstructor" forms and mixins]
I don't remember why the CLOS committee didn't put anything like this
into the proposed standard. Maybe we thought it was the Compiler
committee's business, maybe we had some disagreement, or maybe we
just ran out of time.
There is a blend of problems here -- partly object-oriented and partly
semantics of compilation. It could be that the buck is getting shuffled
back and forth and nothing being done. Maybe the time just wasn't ripe
for specifying this protocol -- maybe more experience is needed -- but
sooner or later the user-community will be "push coming to shove" and
the lack of a portable interface could be damaging.
re: [fasling out classes "by name"]
I don't see how any other way could work, actually, since two distinct
compiled files that refer to a class by the same name must end up
referring to the same metaobject after loading.
Right. Separate compilation seems to be the clinching argument.
Wait. Fasling out classes by name is not always the right thing
to do, and any institutionalization of JonL's and Moon's comments
will probably be a mistake.
In recent proposals, fasl-ing out of classes is not specially addressed
by the proposed STANDARD-OBJECT fasdumping protocol, so it's not so
important that we get this ironed out immediately. Still, I think the
following points need to be made:
1. If anything like a "mixin manager" is being used to create classes
on the fly, such classes should be dumped not as names, but as
mixture specifications, perhaps lists of names.
2. In general, dynamic class creation may result in classes which
are nameless, have gensyms for names, or have names which do not
fully reflect their nature (such as the mixins of #1). Yet such
classes may well have a sensible meaning which is independent
of the current Lisp instance, and which can be transported across
load boundaries; such classes need a way to encode this meaning
in a non-symbol form.
2a. An interesting example of dynamic class creation which shows up less
in dynamically typed languages is the construction of parametrized
types. After instantiating a PT, you compile its methods (or
whatever you call the code is associated with it) with formal type
parameters filled in with actuals. This means that the methods can
be efficiently compiled for the PT instantiation, using any extra
information that the actual type parameters give. For example,
"stack of character" can use character arrays internally, while
"stack of bit" can use bit arrays. These considerations apply
to any language with PTs. Some languages can't even begin to
compile a PT unless it's fully instantiated.
In Lisp, you can program generic stacks using T-arrays, but at a
loss of storage efficiency if you're going to use them for bits.
One solution is to supply a FOO-STACK type for every
implementationally significant sequence element type FOO. A better
solution is to define a class-valued function which takes the
element type as a parameter, and finds or creates a CLOS class with
the appropriate efficient code and data structures. So PTs can have
a place in CLOS, and give another example where symbols don't work
well as class names.
Even better than a class-valued function would be the ability to
give parameters to class names, just as DEFTYPE names accept
parameters. I hope the Meta Object Protocol can be used to do
this. In that case, something like '(STACK CHARACTER) might
make a good fasdumpable class name.
3. This point is concerned less with fasloading from files, but shows
another way that simple symbols are insufficient to refer to classes.
An acid test of an object-oriented system is whether objects of
new classes can be introduced into a running system without breaking it,
and can take participate in existing protocols. Often, such
objects of new class are introduced by loading new modules into
Lisp, so we can assume that whenever an object is loaded, its class
is loaded too.
But what if an object enters a Lisp system alone, perhaps in the
process of IPC, or from an OODB, and it has a class not seen before?
It may then be desirable not only for the class to have a name, but
some indication of where its definition is to be sought, so that it
may be loaded. Such autoloading of classes would be necessary in
systems featuring transfer of objects between Lisps and a large or
growing space of classes.
So, be careful! Mere symbols make good class names only for systems of
limited size, and a fixed class population.
-- JonL --
-- John
∂06-Jan-89 1504 CL-Compiler-mailer Re: issue DEFCONSTANT-SPECIAL
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:03:49 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 05 JAN 89 22:20:13 PST
Date: 5 Jan 89 22:19 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue DEFCONSTANT-SPECIAL
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Tue, 3 Jan 89 15:26:53 MST
To: cl-compiler@sail.stanford.edu
cc: masinter.pa@Xerox.COM
Message-ID: <890105-222013-191@Xerox>
If an implementation "proclaims the variable special" but then admits no
constructs where that proclaimation has an affect, then the result is an
internal detail.
I think the issue is: Is it legal to attempt to lexically rebind a variable
that has been defined with DEFCONSTANT, as might be implied by the wording
on p. 69, and the Proposal is No, it is not, and the Current Practice is
"Most implementations don't allow this."
∂06-Jan-89 1543 CL-Compiler-mailer Re: issue COMPILE-ENVIRONMENT-CONSISTENCY
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:43:03 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06281; Fri, 6 Jan 89 16:41:51 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA08310; Fri, 6 Jan 89 16:41:41 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901062341.AA08310@defun.utah.edu>
Date: Fri, 6 Jan 89 16:41:39 MST
Subject: Re: issue COMPILE-ENVIRONMENT-CONSISTENCY
To: masinter.pa@Xerox.COM
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM, 5 Jan 89 21:27 PST
> Date: 5 Jan 89 21:27 PST
> From: masinter.pa@Xerox.COM
>
> "The compiler may assume that functions that are defined and
> declared INLINE in the compiletime environment will retain the same
> definitions at runtime."
>
> really means is that when calling a function that was originally defined
> and declared INLINE but, at some later point in time, redefined, the
> results are unspecified in that either the old (INLINE-proclaimed) or new
> definition might be invoked.
Exactly. The introductory part of section 2 says very much the same
thing, along with a statement that user code must ensure that things the
compiler is allowed to wire in are defined consistently at both compile
and run time.
> We had considerable debate about 2b (I think on the common lisp mailing
> list.)
I don't remember this. It seemed noncontroversial to us; so many
implementations do this that it appeared just to be a statement of
current practice.
>2d is subsumed by cleanup LISP-SYMBOL-REDEFINITION, is it not?
At least the part about not redefining the functions. This issue was
drafted before we saw LISP-SYMBOL-REDEFINITION.
> 2f means that you can't change a DEFCONSTANT, doesn't it?
Yes. This is merely a restatement of what CLtL already says on p. 68-69.
-Sandra
-------
∂06-Jan-89 1539 Common-Lisp-Object-System-mailer Compilation implications
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:38:27 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA27525; Fri, 6 Jan 89 15:40:07 PST
Received: from lukasiewicz.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA08599; Fri, 6 Jan 89 15:36:42 PST
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA00581; Fri, 6 Jan 89 15:39:08 PST
Date: Fri, 6 Jan 89 15:39:08 PST
From: jrose@Sun.COM (John Rose)
Message-Id: <8901062339.AA00581@lukasiewicz.sun.com>
To: kempf@Sun.COM
Cc: jonl@lucid.com, Common-Lisp-Object-System@Sail.Stanford.edu,
CL-Compiler@Sail.Stanford.edu, cperdue%suntana@Sun.COM
In-Reply-To: kempf@sun.com's message of Fri, 30 Dec 88 11:27:27 PST <8812301927.AA09230@suntana.sun.com>
Subject: Compilation implications
Date: Fri, 30 Dec 88 11:27:27 PST
From: kempf@sun.com
A couple comments on the original and Moon's followup.
...
2) I think Moon's solution of a constructor form which gets executed using
EVAL at load time is the only possible solution to this problem. In particular,
the semantics of quoted constants implied by CLtL is that only symbols can
be expected to be EQ across a FASDUMP, and only characters and numbers can
additionally be expected to be EQL. This has interesting implications
for EQL specializers. Since the only objects which can be
expected to survive a FASDUMP and remain EQL are symbols,
numbers, and characters, these are the
only objects which make sense to have in a DEFMETHOD form with an EQL
That's only true for non-CLOS types. I'm quite pleased that Moon's
solution allows the programmer to define new STANDARD-OBJEcT types
which, like symbols, characters, and numbers, preserve EQL-ness across
dumps. (For example, two Symbolics pathnames are EQL iff they have
equivalent components, thus allowing them to be compared efficiently
and to have well-defined property lists.) This is done by having
a object being fasloaded into a Lisp "look around" in the Lisp for
a pre-existing "equivalent" object, and, if it's found, return that
pre-existing object's reference. The definition of "look around"
and "equivalent" is type-dependent, but the technique is general.
(For symbols, "look around" is FIND-SYMBOL and "equivalent" is
"same print name and package".)
You might call any such type an "EQL-preserving" or "interning" type.
So, EQL specializers can usefully apply to symbols, numbers, characters,
and selected STANDARD-OBJECT classes. Interestingly, STANDARD-CLASS
must be EQL-preserving, since the MAKE-INSTANCE protocol relies on
EQL specializers which point to all the classes.
In my previous message, I argued that mere symbols are not always sufficient
for class names. In the terms of present message, this means that the
implementation of the interning behavior of classes cannot be simply
"dump the class name symbol, and do a FIND-CLASS when loading". In fact,
it may be necessary on occasion to create the class on the fly, when
the name is first seen, just as symbols are created when first seen.
specialized parameter. This makes it important that machinery
be available to add methods to a generic function through a functional
interface, since some of the things one wants to do with EQL methods require
other objects. Part of that machinery is already in Chapter 2
(ADD-METHOD, MAKE-INSTANCE) but part of it is not
(how to make a method function, for example).
These are important points too. But it seems to me that method
definition is essentially an "off-line" activity, like compilation. Or
do the CLOS people envision fast dispatch __and__ fast generic function
redefinition? I assume that fast dispatch is being paid for partly by
heavy crunching at generic function definition time. Or is it all in
the cache action?
...
jak
-- John
∂06-Jan-89 1556 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 6 Jan 89 15:56:07 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06790; Fri, 6 Jan 89 16:54:53 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA08331; Fri, 6 Jan 89 16:54:50 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901062354.AA08331@defun.utah.edu>
Date: Fri, 6 Jan 89 16:54:49 MST
Subject: Re: issue LOAD-TIME-EVAL
To: masinter.pa@Xerox.COM
Cc: cl-compiler@sail.stanford.edu, masinter.pa@Xerox.COM
In-Reply-To: masinter.pa@Xerox.COM, 5 Jan 89 21:41 PST
Date: 5 Jan 89 21:41 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue LOAD-TIME-EVAL
In-Reply-To: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Tue, 3 Jan 89 15:28:30 MST
To: cl-compiler@sail.stanford.edu
Cc: masinter.pa@Xerox.COM
Message-Id: <890105-214203-187@Xerox>
> I don't think (CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
>
> is a good example; you'd do better to say, e.g.,
>
> (defmacro cons-self (x) `(cons ,x ,x))
>
> (cons-self (load-time-value (compute-it)))
>
> the macro expansion of load-time-value might contain EQ structures. This is
> a pretty subtle point that really has to do with macro-expansion-caching --
> you'd be better off explaining what you're outlawing here.
It doesn't really have anything to do with macro expansion caching.
It is true that macro expansion is the most likely way of getting
multiple references to a LOAD-TIME-VALUE form, so your example
probably is better. However, the idea here is to clarify what the
statement in a previous paragraph means about the interpreter being
allowed to evaluate a LOAD-TIME-VALUE form "only once". It's
legitimate to do a code walk before evaluation, but it's not
legitimate to cache LOAD-TIME-VALUE forms and resulting values and do
a lookup based on EQness of source code expressions.
-Sandra
-------
∂06-Jan-89 1607 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Jan 89 16:07:14 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 516775; Fri 6-Jan-89 19:06:00 EST
Date: Fri, 6 Jan 89 19:05 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue SHARP-COMMA-CONFUSION
To: Masinter.PA@Xerox.COM
cc: CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: <890105-213421-186@Xerox>
Message-ID: <890106190541.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
I disagree that there is anything even remotely bad about #. and I would
see no reason to flush it under any circumstances. In my opinion, it is
not a barrier to program-analyzing programs because its semantics is
`pretend I had really typed this'. An example of a place where I might
use #. is
(defun foo (x)
(if x #.(format nil "This string is very long and I want to ~
~%type it in my editor buffer with nice~
~%indentation, but I want Lisp to ignore that
~%indentation.")))
I disagree that #+ and #- are a good idea to consider flushing even in the
most optimistic of worlds. What we should be anxious to do is to make the
language useful enough that the need to appeal to them is rare, but the
fact is that having these things is an acknowledgement that it's hard to
plan for things you didn't plan for. To suggest that you can designed your
language so well that these would never be needed is haughtier than I'm
prepared to be about CL's design.
I hope no one will pursue these supposed wishes of yours because
discussion on the issue could easily waste a lot of time to no good end.
∂06-Jan-89 2109 Common-Lisp-Object-System-mailer Compilation implications
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Jan 89 21:07:56 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 516877; Sat 7-Jan-89 00:06:25 EST
Date: Sat, 7 Jan 89 00:05 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Compilation implications
To: John Rose <jrose@Sun.COM>
cc: kempf@Sun.COM, jonl@lucid.com, Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU, cperdue%suntana@Sun.COM
In-Reply-To: <8901062339.AA00581@lukasiewicz.sun.com>
Message-ID: <19890107050551.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 6 Jan 89 15:39:08 PST
From: jrose@Sun.COM (John Rose)
So, EQL specializers can usefully apply to symbols, numbers, characters,
and selected STANDARD-OBJECT classes. Interestingly, STANDARD-CLASS
must be EQL-preserving, since the MAKE-INSTANCE protocol relies on
EQL specializers which point to all the classes.
As I pointed out in an earlier message, translation of parameter specializer
names to parameter specializers occurs at load time, not at compile time.
Thus the available space of EQL specializers is not affected by the behavior
of COMPILE-FILE and LOAD.
Now you understand why CLOS uses (EQL <form>) where CommonLoops used
(QUOTE <object>).
In my previous message, I argued that mere symbols are not always sufficient
for class names. In the terms of present message, this means that the
implementation of the interning behavior of classes cannot be simply
"dump the class name symbol, and do a FIND-CLASS when loading". In fact,
it may be necessary on occasion to create the class on the fly, when
the name is first seen, just as symbols are created when first seen.
As far as I know, nothing in CLOS, not even in metaobjects, requires the
ability to dump classes with COMPILE-FILE and load them with LOAD. The
programmer writing a particular MAKE-LOAD-FORM method might indeed
implement the behavior you describe, or some other behavior, for their
particular class, but I don't think the core CLOS language requires
this.
specialized parameter. This makes it important that machinery
be available to add methods to a generic function through a functional
interface, since some of the things one wants to do with EQL methods require
other objects. Part of that machinery is already in Chapter 2
(ADD-METHOD, MAKE-INSTANCE) but part of it is not
(how to make a method function, for example).
This is chapter 3 (metaobject) business. It's probably just an accident
that a few bits of it leaked into chapter 2.
These are important points too. But it seems to me that method
definition is essentially an "off-line" activity, like compilation. Or
do the CLOS people envision fast dispatch __and__ fast generic function
redefinition? I assume that fast dispatch is being paid for partly by
heavy crunching at generic function definition time. Or is it all in
the cache action?
CLOS is a language, not an implementation. The CLOS language does not
specify the speed of particular operations. That's a matter for
implementations to decide based on their own tradeoffs.
∂06-Jan-89 2139 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 6 Jan 89 21:39:21 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA08608; Fri, 6 Jan 89 18:06:36 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA08409; Fri, 6 Jan 89 18:06:00 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901070106.AA08409@defun.utah.edu>
Date: Fri, 6 Jan 89 18:05:59 MST
Subject: Re: issue SHARP-COMMA-CONFUSION
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Masinter.PA@Xerox.COM, CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 6 Jan 89 19:05 EST
I agree with Kent on this one. The time when #., #+, and #- are
processed is *always* read-time, and they always behave the same way
regardless of whether the thing that is doing the reading is the
compiler, LOAD, or some user-written program-analyzing program.
Incidentally, the writeup for this issue does point out that program
analyzers can (theoretically, at least) handle #, by fiddling with the
readtable.
In any case, since the other read macros have nothing to do with
compilation, a proposal to change them wouldn't really fall into our
domain.
-Sandra
-------
∂06-Jan-89 2207 Common-Lisp-Object-System-mailer Re: Compilation implications
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Jan 89 22:07:07 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 516917; Sat 7-Jan-89 01:04:36 EST
Date: Sat, 7 Jan 89 01:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Compilation implications
To: David N Gray <Gray@DSG.csc.ti.com>
cc: Jon L White <jonl@lucid.com>, Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <2809040762-4991819@Kelvin>
Message-ID: <19890107060409.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 5 Jan 89 19:06:02 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> Probably it would be a better idea for MAKE-LOAD-FORM to return two
> values, where the first value is a form that will create the object and
> the second value is a form that will further initialize the object?
> This way the order of evaluation requirement is more explicit. It's
> upward compatible since the second value can be NIL if you don't need
> it.
Yes, that sounds good except for the problem of how to pass the object to
the second form.
> ... suppose we plug the object returned by
> the first form into the second form and do (schematically):
...
> (WHEN form1.2
> (EVAL (APPEND form1.2 (LIST (LIST 'QUOTE x1)))))
...
This reduces generality because the second form can't use optional
arguments, and it seems a little strange to say that the second value is a
form minus its last argument.
What I had in mind was ((LAMBDA (object) ...code...)). But I like your
suggestion of evaluating the form in an environment where * is bound to the
object better. Other people should check me on this, it might just be that
you appealed to my sense of hackish kludgery.
It would be nicer if we could just use a function, but the last proposal I
saw for what you could use as constants in COMPILE-FILE said you could not
use functions. We could use a LAMBDA expression, I suppose.
> Should I evolve the proposal I sent out the other day along these lines?
Yes, I would like to see that.
I'll update it based on all the received comments as early as I can next week.
∂06-Jan-89 2246 CL-Compiler-mailer Compilation implications
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 6 Jan 89 22:45:28 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate id AA08230g; Fri, 6 Jan 89 22:40:51 PST
Received: by bhopal id AA02511g; Fri, 6 Jan 89 22:43:05 PST
Date: Fri, 6 Jan 89 22:43:05 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901070643.AA02511@bhopal>
To: Gray@DSG.csc.ti.com
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, jrose@Sun.COM,
Common-Lisp-Object-System@Sail.Stanford.edu,
Cl-compiler@Sail.Stanford.edu
In-Reply-To: David N Gray's message of Fri, 6 Jan 89 11:17:49 CST <2809099069-8494933@Kelvin>
Subject: Compilation implications
re: [CLOS Chapter 3 stuff]
Hmm, well maybe portable code won't want to be using that just yet.
re: > Does your macro expander for DEFMETHOD call EVAL to get the object,
> rather than returning a form to be evaluated later?
Yes, the evaluation is being done at macro expansion time. If that's not
right, I'll need to change it.
A few things weigh against the evaluation being done at macroexpansion time:
-- Lucid's DEFSTRUCT implementation does some of the work of the
defstruct definition at macro-expansion time, and the rest at
the subsequent evaluation time (when that macro-expanded form
is finally evaluated). This has caused numerous headaches, such
as in trying to fully macroexpand a form like:
(progn
(defstruct foo a b c)
(defstruct (bar (:include foo)) d e)
)
[The bug is that the second defstruct cannot be macroexpanded,
because it cannot :include the first one until the first defstruct
has been truly evaluated.] Were it not for other constraints, we
probably would have fixed this long ago. In summary, always have a
macroexpander return a "simple" program rather than "part program,
and part (constant) data containing pre-calculated evaluations."
-- Treated as a program, the (FOO) in a specializer (EQL (FOO)) poses
no special problems in cross-compiling; but treating it as a kind
of constant designator (implying object creation at compile time)
requires a tremendous amount more of the runtime class hierarchy
to be "present and accounted for" in the cross-compiling environment.
-- In PCL, Gregor took the "program" approach rather than the "data" one;
Moon has gone on record favoring it too. And although I dislike the
approach taken for DEFCONSTANT by most implentations, it too favors
the "program" approach. It sure would be nice for eql specializers
not to have to fall into the horrible controversy surrounding
compiled constants (i.e., those other than DEFCONSTANT constants).
-- JonL --
P.S. This part of the discussion seemed relevant to the cl-compiler group
also; messages dealing primarly with CLASS semantics, however,
probably don't need to be cc'd there.
∂06-Jan-89 2247 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Jan 89 22:46:10 PST
Received: from Semillon.ms by ArpaGateway.ms ; 06 JAN 89 16:24:49 PST
Date: 6 Jan 89 16:23 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue LOAD-TIME-EVAL
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Fri, 6 Jan 89 16:54:49 MST
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
cc: masinter.pa@Xerox.COM, cl-compiler@sail.stanford.edu
Message-ID: <890106-162449-1426@Xerox>
I don't want to give anyone an idea that they can use #n= and #n# in code
with impunity. I'd like to outlaw it.
Can your compiler deal with
(list '#1=(a b . #1#))?
I tried compiling that and got a stack overflow.
∂07-Jan-89 0123 CL-Compiler-mailer issue LOAD-TIME-EVAL
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Jan 89 01:23:10 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate id AA08372g; Sat, 7 Jan 89 01:19:12 PST
Received: by bhopal id AA03022g; Sat, 7 Jan 89 01:21:27 PST
Date: Sat, 7 Jan 89 01:21:27 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901070921.AA03022@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cl-compiler@sail.stanford.edu, alarson@src.honeywell.com
In-Reply-To: Sandra J Loosemore's message of Fri, 6 Jan 89 16:54:49 MST <8901062354.AA08331@defun.utah.edu>
Subject: issue LOAD-TIME-EVAL
At least one "wizard" at Lucid was thoroughly confused by the
(CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
example. Perhaps it needs to be fleshed out.
I liked Aaron Larson's comment on the matter:
"I was under the impression that the only loophole permitting the
compiler to copy/substitute otherwise non EQ forms was with regard
to QUOTE."
That is, one might conceivable think of coalescing the two calls to
LOAD-TIME-VALUE because of a sort of similarity to QUOTE. But as
Aaron further noted, the compiler cannot reduce the calls to CONS
in the structurally isomorphic form:
(EQ #1=(CONS 'A 'B) #1#)
So why should LOAD-TIME-VALUE be any different.
Also your comment about constraints on the interpreter could be helpful:
". . . but it's not legitimate to cache LOAD-TIME-VALUE forms and
resulting values and do a lookup based on EQness of source code
expressions."
-- JonL --
∂07-Jan-89 1323 CL-Compiler-mailer issue COMPILED-FUNCTION-REQUIREMENTS
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 7 Jan 89 13:23:34 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA23396; Sat, 7 Jan 89 14:22:28 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA09002; Sat, 7 Jan 89 14:22:26 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901072122.AA09002@defun.utah.edu>
Date: Sat, 7 Jan 89 14:22:24 MST
Subject: issue COMPILED-FUNCTION-REQUIREMENTS
To: cl-compiler@sail.stanford.edu
I mailed out version 1 of this new issue on Tuesday. Does anybody have
anything to say about it, or objections to passing it on to X3J13 at this
time? It's clearly marked **DRAFT** and I have no intention to ask for a
vote on it yet. Please let me know ASAP if you have a problem with this.
-Sandra
-------
∂07-Jan-89 1453 CL-Compiler-mailer Re: issue COMPILED-FUNCTION-REQUIREMENTS
Received: from ti.com by SAIL.Stanford.EDU with TCP; 7 Jan 89 14:53:13 PST
Received: by ti.com id AA07687; Sat, 7 Jan 89 16:51:24 CST
Received: from Kelvin by tilde id AA20832; Sat, 7 Jan 89 16:41:31 CST
Message-Id: <2809205067-775570@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Sat, 7 Jan 89 16:44:27 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue COMPILED-FUNCTION-REQUIREMENTS
In-Reply-To: Msg of Sat, 7 Jan 89 14:22:24 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
I agree that the type COMPILED-FUNCTION currently lacks a portable
meaning, and some kind of clarification is in order. While the
definition you propose sounds reasonable, I'm not sure how useful it
would be. Having determined that an object satisfies
COMPILED-FUNCTION-P, you would know it possesses these characteristics,
but so what? What would you do with it differently depending on that?
I hadn't thought about this before, but just off hand the only useful
portable interpretation for this I can think of would be:
* An object that satisfies COMPILED-FUNCTION-P is a valid argument for
DISASSEMBLE.
* An object that satisfies FUNCTION-P but not COMPILED-FUNCTION-P is
a reasonable argument to be passed to the COMPILE function.
(However, it still might not be valid if it is an interpreter
closure.)
We make good use of the type COMPILED-FUNCTION in our implementation,
but all of the accessor functions for objects of that type are
non-standard, which makes me wonder if it might be best to just remove
this type from the standard along with BIGNUM.
By the way, for the "current practice" section, on the Explorer, the
COMPILE function can return an object of either type COMPILED-FUNCTION
or LEXICAL-CLOSURE, where the latter consists of two components -- an
environment and a COMPILED-FUNCTION. So this proposal would be a change
for us, but now that I think about it, the current behavior doesn't seem
to fit too well with the definition of COMPILED-FUNCTION-P in CLtL.
Our implementation also has a confusion about whether microcoded
functions should be considered compiled or not.
∂07-Jan-89 1650 CL-Compiler-mailer Re: issue COMPILED-FUNCTION-REQUIREMENTS
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 7 Jan 89 16:50:09 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA28229; Sat, 7 Jan 89 17:48:57 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA09104; Sat, 7 Jan 89 17:48:53 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901080048.AA09104@defun.utah.edu>
Date: Sat, 7 Jan 89 17:48:52 MST
Subject: Re: issue COMPILED-FUNCTION-REQUIREMENTS
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Sat, 7 Jan 89 16:44:27 CST
> Date: Sat, 7 Jan 89 16:44:27 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> We make good use of the type COMPILED-FUNCTION in our implementation,
> but all of the accessor functions for objects of that type are
> non-standard, which makes me wonder if it might be best to just remove
> this type from the standard along with BIGNUM.
That's also a possibility. One of the other things I was thinking about
was putting the various constraints on COMPILE and COMPILE-FILE instead
of the COMPILED-FUNCTION type. I could write this up as an alternate
proposal.
I also made good use of the COMPILED-FUNCTION type internally in
A-Lisp, but much of the need for it goes away with the introduction of
the FUNCTION-TYPE proposal. COMPILED-FUNCTION was used mostly to
distinguish "true" functions from symbols and lambda lists, so if you
declared something to be a COMPILED-FUNCTION, the compiler could use a
very efficient opencoding for funcalls.
Are there any implementations that use distinguished representations
for COMPILED-FUNCTIONs that use type declarations in this way? If so,
that might be an argument for retaining the type specifier (to make
the usage portable).
-Sandra
-------
∂07-Jan-89 2109 CL-Compiler-mailer Re: **DRAFT** Issue COMPILER-VERBOSITY, version 5
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Jan 89 21:09:22 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 07 JAN 89 21:00:36 PST
Date: 7 Jan 89 21:00 PST
From: masinter.pa@Xerox.COM
Subject: Re: **DRAFT** Issue COMPILER-VERBOSITY, version 5
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Sat, 7 Jan 89 10:45:08 MST
To: cl-compiler@sail.stanford.edu
cc: masinter.pa@Xerox.COM
Message-ID: <890107-210036-2879@Xerox>
The benefits seem pretty weak given the cost. Why would I want a portable
way to control how much information is printed by COMPILE-FILE?
I can see wanting to have a portable way to compile a file, so I can
distribute a standard procedure for compiling my system, but most of the
print/informational stuff varies so widely, is of different format, and is
generally of use only while debugging code in a single system.
The Medley version of COMPILE-FILE, for example, has several other
control-parameters that one might also want "portable" control over, except
that those aren't really portable: for example, you can ask it for an
assembly listing of everything it compiles; you can give it a pathname for
a new file for "errors" and have it automatically rebind *standard-error*
to that file, etc.
(compile-file input-file &key :output-file :lap-file :error-file
:errors-to-terminal :file-manager-format :process-entire-file :load)
I don't see any more need for making these "portable" options than I do
:verbose and :print.)
∂07-Jan-89 2109 CL-Compiler-mailer Re: **DRAFT** Issue COMPILER-DIAGNOSTICS, version 8
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Jan 89 21:09:29 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 07 JAN 89 21:02:21 PST
Date: 7 Jan 89 21:01 PST
From: masinter.pa@Xerox.COM
Subject: Re: **DRAFT** Issue COMPILER-DIAGNOSTICS, version 8
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Sat, 7 Jan 89 10:43:26 MST
To: cl-compiler@sail.stanford.edu
Message-ID: <890107-210221-2884@Xerox>
I'm puzzled by all this extra mechanism. Most of the errors I get when
compiling are errors underneath macro expanders, and none of the mechanisms
you've added seem to help with dealing with those in a more automatic way.
∂07-Jan-89 2221 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Jan 89 22:20:54 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate id AA08761g; Sat, 7 Jan 89 22:16:34 PST
Received: by bhopal id AA05596g; Sat, 7 Jan 89 22:18:49 PST
Date: Sat, 7 Jan 89 22:18:49 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901080618.AA05596@bhopal>
To: sandra%defun@cs.utah.edu
Cc: SEB1525@draper.com, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Sandra J Loosemore's message of Fri, 6 Jan 89 16:33:48 MST <8901062333.AA08280@defun.utah.edu>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Sandra, I'm still confused by the comments in your msg of Jan 3:
Seriously, I think it would be an extremely bad idea to make
EVAL-WHEN's notion of when to perform compile-time magic different
than the standard notion of top-level-ness. Besides it being
confusing, one wouldn't be able to use EVAL-WHEN to implement the
magical compile-time behavior of the various defining macros. I
suppose that if we made the defining macros behave the same way, it
would be somewhat more reasonable, but in that case why not just
change the definition of top-level?
I don't see what you are getting at w.r.t. "defining macros".
This was (I think) in response to my suggestion to revive the working
implementation of EVAL-WHEN that did a MACROLET of EVAL-WHEN in order
to make nested, innner EVAL-WHEN's with the COMPILE situation work
correctly (i.e., not to evaluate such forms 2↑<n-1> times where n
is the level of nesting). This "working definition" has the virtue
of consistency with CLtL's prescriptions (on page 70) such that
1. The COMPILE situation "inherits" -- namely, the following
form will cause (blast-off) to be executed in the compiler
environment, even though it is wrapped in eval-when(load):
(eval-when (eval compile load)
(eval-when (load)
(blast-foo)))
2. Each form evaluated in "compile-time-too" mode is evaluated
only once.
I was tempted to agree with Bacher's counter example on altering the
notion of toplevel. It would be a counterexample if there are *any*
other operations that discriminate between toplevel and non-toplevel.
Currently the evaluation of defining forms and of the "7-extremely
randoms" seems to be it. In short, he has found a flaw in the design
if there are any such operations; and if there aren't any such operations,
then the entire issue is moot except for the double-evaluation problem
in EVAL-WHEN. So why not just let EVAL-WHEN take the brunt of the
extra definitional complexity?
-- JonL --
∂08-Jan-89 1022 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 8 Jan 89 10:21:10 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA01749; Sun, 8 Jan 89 11:17:13 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA09469; Sun, 8 Jan 89 11:17:04 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901081817.AA09469@defun.utah.edu>
Date: Sun, 8 Jan 89 11:17:03 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: Jon L White <jonl@lucid.com>
Cc: sandra%defun@cs.utah.edu, SEB1525@draper.com,
cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Jon L White <jonl@lucid.com>, Sat, 7 Jan 89 22:18:49 PST
I guess what's obvious to me is not obvious to you. Perhaps an
example might help clarify this.
(eval-when (eval compile load)
(defmacro bar ...))
Suppose we do as you suggest and say that the bodies of top-level
EVAL-WHENs continue to be top-level, but prevent nested EVAL-WHENs
from doing COMPILE evaluation. Then, since the macro definition for
BAR is at top-level, it must cause some compile-time magic to happen
when it is compiled (processing for the LOAD situation). This implies
that you couldn't implement DEFMACRO by expanding it into an EVAL-WHEN,
because the required magic actions would be suppressed.
My claim is that there is really no need for the macro definition of
BAR to cause any compile time magic when it is processed for the LOAD
situation. After all, BAR has already been fully defined in the
compiler's environment because of the COMPILE situation being
specified in the EVAL-WHEN. In other words, the multiple evaluation
problem applies just as much to nested defining macros as nested
EVAL-WHENs. The simplest way to deal with both problems is to just
say that top-level-ness is not passed through to the body at all.
I think that perhaps people are reading more into the term "top-level"
than it really implies. Under our current set of proposals, the only
things that top-level-ness is used for are:
- to determine when it is appropriate to perform compile-time
side effects for EVAL-WHEN and various defining macros.
- to apply some constraints on the order of processing.
Also, I have a problem with the example you cite:
> 1. The COMPILE situation "inherits" -- namely, the following
> form will cause (blast-off) to be executed in the compiler
> environment, even though it is wrapped in eval-when(load):
> (eval-when (eval compile load)
> (eval-when (load)
> (blast-foo)))
Under the current proposal, BLAST-FOO will not be called at compile
time regardless of whether EVAL-WHEN passes through top-level-ness.
(This is because the COMPILE processing for the outer EVAL-WHEN passes
the inner EVAL-WHEN to EVAL, which looks only for the EVAL situation.)
If this is seen as a serious compatibility problem, the only thing I
can see to do about it is go back to describing EVAL-WHEN with a
compile-time-too state variable, as in CLtL, which would fix the
problem with multiple evaluations without messing with the definition
of top-level-ness. At this point, I'm inclined to agree with Cris
that we ought to try to "fix" the nesting behavior of EVAL-WHEN,
though.
-Sandra
-------
∂08-Jan-89 1333 CL-Compiler-mailer Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 8
Received: from moon.src.honeywell.com (ALTURA.HONEYWELL.COM) by SAIL.Stanford.EDU with TCP; 8 Jan 89 13:33:44 PST
Return-Path: <alarson@src.honeywell.com>
Received: from pavo.SRC.Honeywell.COM
by moon.src.honeywell.com (5.59/smail2.6.3/06-17-88)
id AA25186; Sun, 8 Jan 89 15:32:20 CST
Posted-Date: Sun, 8 Jan 89 15:30:47 CST
Received: by pavo.src.honeywell.com (3.2/SMI-3.2)
id AA14202; Sun, 8 Jan 89 15:30:47 CST
Date: Sun, 8 Jan 89 15:30:47 CST
From: alarson@src.honeywell.com (Aaron Larson)
Message-Id: <8901082130.AA14202@pavo.src.honeywell.com>
To: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 7 Jan 89 10:32:22 MST <8901071732.AA08861@defun.utah.edu>
Subject: Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 8
...
(2) The affected defining macros and their specific side effects are
as follows....
DEFCONSTANT: The compiler must recognize that the symbol names a
constant. An implementation may choose to evaluate the value-form at
compile time, load time, or both. Therefore users must ensure that
the value-form is evaluable at compile time (regardless of whether or
not references to the constant appear in the file) and that it always
evaluates to the same value.
Presumably this would make (defconstant foo (list 'a)) an error. Why is it
necessary to permit an implementation to evaluate the constant form at both
compile and load time?
Several references to "the same file" Does this mean that the compiler can
(or is required to) forget the info once the file has been compiled?
Presumably if the compiler compiles a definition of FOOMAC, then loads a
different version of FOOMAC (say from a different file) later compilations
will use the LOADED version right? I.e. there must be some precedence
between databases maintained by the compiler and the interpreter if they
are allowed to be separate.
DEFSTRUCT: ... The #S reader syntax may or may not be
available at compile time.
Can't this be resolved one way or the other?
DEFINE-CONDITION: The rules are essentially the same as those ...
DEFCLASS: The compiler must make the class name be recognized ...
DEFGENERIC and DEFMETHOD: These are not required to perform ...
The descriptions of DEFCLASS, DEFGENERIC, and DEFMETHOD are significantly
weeker than the specification of what they do we just received in the CLOS
chapter 3 spec. If conditions were allowed/required to be classes, then
similar things would apply to DEFINE-CONDITION. Perhaps these should be
dropped, in favor of the CLOS spec.
DEFINE-METHOD-COMBINATION: The compiler is not required to perform
any compile-time side-effects.
The CLOS spec is silent about DEFINE-METHOD-COMBINATION (at least as far as
I've read), but I presume similar comments apply.
∂08-Jan-89 1550 CL-Compiler-mailer Re: Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 8 Jan 89 15:49:34 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA09767; Sun, 8 Jan 89 16:47:45 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA09604; Sun, 8 Jan 89 16:46:59 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901082346.AA09604@defun.utah.edu>
Date: Sun, 8 Jan 89 16:46:58 MST
Subject: Re: Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, version 8
To: alarson@src.honeywell.com (Aaron Larson)
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: alarson@src.honeywell.com (Aaron Larson), Sun, 8 Jan 89 15:30:47 CST
> Date: Sun, 8 Jan 89 15:30:47 CST
> From: alarson@src.honeywell.com (Aaron Larson)
>
> Presumably this would make (defconstant foo (list 'a)) an error.
The intention was that the behavior would be "unspecified"; you don't
know whether the compile-time or load-time value would prevail, but it's
not a crash-and-burn situation. See issue COMPILE-ENVIRONMENT-CONSISTENCY.
Perhaps we should say that values should be "equivalent" instead of
"the same".
> Why is it
> necessary to permit an implementation to evaluate the constant form at both
> compile and load time?
Because, after debating this issue at great length, we weren't able to
come up with a consensus. As it says in the rationale section, the
wording is intended to legitimize all of the variants.
> Several references to "the same file" Does this mean that the compiler can
> (or is required to) forget the info once the file has been compiled?
It can, but is not required to. For instance, it would be a valid
implementation technique for COMPILE-FILE to fork a child process to
do all the work.
> Presumably if the compiler compiles a definition of FOOMAC, then loads a
> different version of FOOMAC (say from a different file) later compilations
> will use the LOADED version right? I.e. there must be some precedence
> between databases maintained by the compiler and the interpreter if they
> are allowed to be separate.
This is a problem we are still working on. Lately there has been a
drive to use environment objects as the database for the compiler; for
example, the CLOS spec appears to assume that something like this is
going on, and that the information in the environment overrides anything
in the ordinary run-time environment. There are many unresolved issues
here, because CLtL says that environments need only contain information
for expanding local macros which have a clearly defined lexical scope.
> DEFSTRUCT: ... The #S reader syntax may or may not be
> available at compile time.
>
> Can't this be resolved one way or the other?
I suppose we could say it "is an error" to try to use the #S syntax
at compile time, which is more or less the same thing.
> The descriptions of DEFCLASS, DEFGENERIC, and DEFMETHOD are significantly
> weeker than the specification of what they do we just received in the CLOS
> chapter 3 spec.
I have asked the CLOS people several times for assistance with this
issue, but they have not responded to my pleas. What's in our
proposal is the best we could come up with from our understanding of
the issues involved. I'm far from being a CLOS wizard myself and I
haven't had time to look over the new CLOS chapter 3 at all yet.
The specification for DEFINE-CONDITION was derived from the sample
implementation Kent Pitman distributed many moons ago.
-Sandra
-------
∂08-Jan-89 1738 CL-Compiler-mailer Issue: COMPILER-LET-CONFUSION (Version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Jan 89 17:38:23 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 517360; Sun 8-Jan-89 17:59:05 EST
Date: Sun, 8 Jan 89 17:58 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COMPILER-LET-CONFUSION (Version 4)
To: sandra%defun@CS.UTAH.EDU
cc: CL-Compiler@SAIL.Stanford.EDU
Message-ID: <890108175803.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Ok, per your request, here's a total reworking of this issue based on my
view of what COMPILER-LET is about. I've changed nearly every section, so
read carefully.
In the process, the presentation of the ELIMINATE option changed
somewhat. Although I don't personally support that option, I've tried
to still cast it as something people could reasonably decide to vote for
once they understand the issues. If some part of the presentation
doesn't seem fair, either submit a correction or let me know and I will.
Statements of support (for either option) for inclusion in the
Discussion are solicited anew from anyone with an opinion on this topic.
-----
Issue: COMPILER-LET-CONFUSION
Forum: Compiler
References: CLtL p. 112
Category: CHANGE
Edit History: V1, 27 Sep 1988, Sandra Loosemore (initial version)
V2, 04 Oct 1988, Sandra Loosemore (add another example)
V3, 31 Oct 1988, Sandra Loosemore (only proposal ELIMINATE)
V4, 08 Jan 1989, Kent M. Pitman (new alternative)
Problem Description:
The description of the COMPILER-LET special form in CLtL is confusing
to many people. There are no examples provided to make it clear how it
is supposed to be used. The only description which is offered is overly
concrete, which have led to confusion about the intent of COMPILER-LET,
and about it's implementability.
The intent of COMPILER-LET was to permit information to be communicated
between macros by use of dynamic variables at macroexpansion time.
It was not necessary to the intended uses of COMPILER-LET that such
variables ever be bound at execution time.
Unfortunately, probably because some implementations did not primitively
support COMPILER-LET at the time CLtL was written, an exception was
permitted to make COMPILER-LET `more or less work' in interpreters:
the COMPILER-LET variables were permitted to be bound at execution time.
The problem was further compounded by the fact that CLtL presented this
exception as part of COMPILER-LET's contract rather than as an
implementation note, and by the fact that no examples of actually using
COMPILER-LET correctly are provided.
Subtle bugs can be introduced because of the different handling of the
variable bindings in the interpreter and the compiler. In compiled
code, the bindings are only lexically visible during the expansion of
macros at compile time, while in interpreted code the bindings have
dynamic scope and may also be seen during ordinary evaluation if
evaluation and macroexpansion happen concurrently.
Further compatibility problems can result from the value forms being
evaluated in a null lexical environment in the compiler and the ordinary
lexical environment in the interpreter.
Background and Analysis:
It should be clear up front that COMPILER-LET is not computationally
essential. Most (if not all) uses of it can be rewritten using MACROLET.
However, this is a little misleading because it's like saying you can
do without LET given that you have FLET. You can, but you lose some things
in the process:
Just as rewriting a LET using FLET might slow your computation, so too
a rewrite of COMPILER-LET using MACROLET might slow things down. However,
compilation speed is generally not weighted as heavily as execution speed
by many people, so the loss of speed here may not be as important.
Just as rewriting a LET using FLET might obscure the simplicity of your
intent, so too rewriting COMPILER-LET using MACROLET might obscure your
intent. You'd probably get used to recognizing idioms if you used it often
enough. Certainly this would be true if you didn't have LET. However,
COMPILER-LET is used less often, so not having it would mean that the
code you wrote instead would be much harder to read because people
wouldn't have the necessary familiarity with the idioms involved and so
wouldn't always understand them.
Just as rewriting a LET using FLET is harder to do (if not impossible) in
the presence of side-effects to the LET variables, so too rewriting
COMPILER-LET in terms of MACROLET is harder to do (if not impossible) in
the presence of side-effects.
A typical use of COMPILER-LET (without side-effects) might be:
(defvar *local-type-declarations* '())
(defmacro local-type-declare (declarations &body forms)
`(compiler-let ((*local-type-declarations*
(append ',declarations *local-type-declarations*)))
,@forms))
(defmacro typed-var (var)
(let ((type (assoc var *local-type-declarations*)))
(if type `(the ,(cadr type) ,var) var)))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
This can be rewritten straightforwardly by someone familiar with doing so,
but the result is not as readable to those not familiar with the idioms:
(defmacro local-type-declare (declarations &body forms)
(local-type-declare-aux declarations forms))
(defmacro typed-var (var) var)
(eval-when (eval compile load)
(defun local-type-declare-aux (declarations forms)
`(macrolet ((typed-var (var)
(let ((type (assoc var ',declarations)))
(if type `(the ,(cadr type) ,var) var)))
(local-type-declare (new-declarations &body new-forms)
(local-type-declare-aux
(append new-declarations ',declarations)
new-forms)))
,@forms)))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
The issues are these:
- Is it possible to implement COMPILER-LET in a usefully consistent
way in all implementations?
- Is the cost of providing a useful and compatible implementation of
COMPILER-LET worth any associated cost?
Two proposals are presented below:
- Option REPAIR argues that COMPILER-LET provides interesting
functionality that can be implemented in a manner that is usefully
consistent across implementations, and that the associated cost
is low enough for it to be worthwhile to do so.
- Option ELIMINATE presents a fall-back position for those who
either find that COMPILER-LET is not possible to implement in
a usefully consistent way in all implementations, or for those who
agree that although technically possible to do so, the cost is too
high.
Proposal (COMPILER-LET-CONFUSION:REPAIR):
Strike the existing definition of COMPILER-LET. Redefine it as follows:
COMPILER-LET [Special form]
COMPILER-LET is similar to LET, but its bindings are visible only
during macroexpansion of forms in the body, not during the runtime
execution of those forms.
The intent is that some macros might macroexpand into calls to
COMPILER-LET in which the body would the contain references to
macros which access the variables in the COMPILER-LET.
The initial value forms of the bindings, if any, are always
evaluated in a null lexical context, regardless of whether the
COMPILER-LET expression is being interpreted or compiled.
The initial value forms of the bindings, if any, are evaluated in
a dynamic context where the bindings of any lexically enclosing
COMPILER-LET are visible, and where dynamic execution-time
environment may or may not be visible.
Implementation Note: Permitting the execution-time dynamic
environment to be visible when initializing COMPILER-LET variables
is a concession to some interpreters which may have to do this in
order to keep the cost down. Where feasible, implementors should
try not to make the runtime environment visible.
Rationale:
This gives a consistent description of COMPILER-LET which separates
issues of intent from those of implementation in a way that makes it
possible for portable code to make serious use of it, and which does
not force gratuitous incompatibilities between interpreters and
compilers.
This description of COMPILER-LET can be implemented without undue
cost by all implementations. See "Cost to Implementors" for details.
Cost to Implementors:
Modest to small:
In compiled code, and in interpreters doing a one-time semantic
prepass, it should be fairly easy for COMPILER-LET to cause the
variables to get bound (using PROGV) during semantic analysis.
In interpreters which do not do a semantic-prepass, it is necessary
to fully macroexpand the body. Assuming the presence of a
SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
could look like:
(DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
(SETQ BINDINGS ;; Assure no non-atom bindings
(MAPCAR #'(LAMBDA (BINDING)
(IF (ATOM BINDING) (LIST BINDING) BINDING))
BINDINGS))
(PROGV (MAPCAR #'CAR BINDINGS)
(MAPCAR #'CDR BINDINGS)
(SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))
This reduces the problem of writing a program capable of doing a
full macroexpansion. Many systems already have such a facility.
Pitman wrote such a facility in Cloe Runtime in order support
SYMBOL-MACROLET (before it was christened a special form); it was
about 750 lines of relatively straightforward, well-commented code.
Another approach, which has not been fully explored, but which seems
plausible, is for COMPILER-LET to annotate the environment with the
bindings, and then to instantiate the bindings for the duration of
each call to MACROEXPAND-1. To accomodate SETQ of COMPILER-LET
variables, some care would be needed to assure that assignments to
these variables were recorded at the end of such a binding context
in order to correctly affect subsequent macroexpansions in the same
COMPILER-LET scope. This technique might be slightly slower, but
could avoid the need for a special code-walker. Also, the slowness
would generally only be incurred when a COMPILER-LET was actually
being processed, which (depending on the application) might not be
the common case.
Cost to Users:
Code currently depending on this feature is either non-existent or
already not portable (due to wide variation in implementation
strategy for COMPILER-LET).
Most users will probably be happy for any interpretation which offers
them a future short at portability.
Proposal (COMPILER-LET-CONFUSION:ELIMINATE):
Remove COMPILER-LET from the language.
Rationale:
This is a fallback position for those who believe that COMPILER-LET
is not implementable in consistently useful way across implementations,
or for those who believe that a consistently useful implementation
would be prohibitively expensive.
Some people think that having one less special form would simplify the
language.
Cost to Implementors:
Minimal. Implementations could continue to support COMPILER-LET as
an extension.
Cost to Users:
People who use COMPILER-LET would have to rewrite their programs to use
some other construct. As discussed above, most uses of COMPILER-LET
for communication between macros can be handled using MACROLET, though
some perspecuity may be lost in the process.
Current Practice:
Some implementations have implemented the description in CLtL.
Users of those implementations (quite reasonably) can't figure how to
use COMPILER-LET and so don't use it much.
Some implementations (the onces from which COMPILER-LET originally came)
continue to use their pre-CLtL semantics. These semantics are useful, though
incompatible with CLtL (which they largely consider to simply be in error).
Users of those implementations probably use COMPILER-LET somewhat more
often since it has an intelligible behavior, but their code is not portable
since it relies on behaviors which are either contrary to or not guaranteed
by CLtL.
Benefits:
Either way, a potential area of incompatibility between compiled and
interpreted code would be eliminated.
Either way, a potential area of portability trouble would be very
drastically reduced (in the case of the REPAIR option) or eliminated
(in the case of the ELIMINATE option).
Discussion:
[Most opinions previously expressed on this topic were given before
a balanced set of options were provided. Since I hope some people
may want to change their votes now that two "reasonable" options
are presented, I've removed statements of preference and hope that
people will state a position anew based on this new writeup. -kmp]
Pitman strongly favors COMPILER-LET-CONFUSION:REPAIR.
∂08-Jan-89 1839 CL-Compiler-mailer issue LOAD-TIME-EVAL
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 8 Jan 89 18:39:46 PST
Received: from blacksox ([192.9.201.39]) by heavens-gate.lucid.com id AA00184g; Sun, 8 Jan 89 18:35:33 PST
Received: by blacksox id AA00923g; Sun, 8 Jan 89 18:37:56 pst
Date: Sun, 8 Jan 89 18:37:56 pst
From: Eric Benson <eb@lucid.com>
Message-Id: <8901090237.AA00923@blacksox>
To: masinter.pa@Xerox.COM
Cc: sandra%defun@cs.utah.edu, masinter.pa@Xerox.COM,
cl-compiler@sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM's message of 6 Jan 89 16:23 PST <890106-162449-1426@Xerox>
Subject: issue LOAD-TIME-EVAL
Date: 6 Jan 89 16:23 PST
From: masinter.pa@Xerox.COM
I don't want to give anyone an idea that they can use #n= and #n# in code
with impunity. I'd like to outlaw it.
Can your compiler deal with
(list '#1=(a b . #1#))?
I tried compiling that and got a stack overflow.
This is a separate problem, covered by one of those many compiler
cleanup issues that have almost the same name (I think there's one
with the words CONSTANT and CIRCULARITY in it). By the way, Lucid's
compiler has no problem with the example you give.
∂08-Jan-89 2011 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 4)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 8 Jan 89 20:11:13 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA13589; Sun, 8 Jan 89 21:10:00 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA09741; Sun, 8 Jan 89 21:09:36 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901090409.AA09741@defun.utah.edu>
Date: Sun, 8 Jan 89 21:09:35 MST
Subject: Re: Issue: COMPILER-LET-CONFUSION (Version 4)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Sun, 8 Jan 89 17:58 EST
Looks generally OK. I don't see anything obviously unreasonable about
your new proposal, but one thing that's definitely missing is an
explicit statement that it's supposed to bind the variables specially.
I'd suggest moving your detailed arguments for not eliminating
COMPILER-LET to the discussion section rather than the problem
statement. I'd like to rebut your claim that the COMPILER-LET example
is more understandable than the MACROLET example; COMPILER-LET is
probably just as confusing to people who are not familiar with its
usage. Both MACROLET and COMPILER-LET are fairly advanced features.
(In my experience, few novice Lispers understand how even simple
macros work.)
And, there is another argument for eliminating COMPILER-LET besides
implementability: some people might think that even your improved
definition is confusing and that the functionality it provides is not
worth the additional complication to the language. For instance, it
seems a little peculiar to me that COMPILER-LET should be allowed to
see dynamic bindings created during ordinary evaluation, but that
ordinary evaluation should not see the dynamic bindings created by
COMPILER-LET.
If you have no objection, I'll come up with a revised version that
incorporates these tweaks. I also noted a few typos in passing.
-Sandra
-------
∂08-Jan-89 2329 CL-Compiler-mailer **DRAFT** issue CONSTANT-COLLAPSING
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 8 Jan 89 23:29:00 PST
Return-Path: <barmar@Think.COM>
Received: from kulla.think.com by Think.COM; Mon, 9 Jan 89 02:24:10 EST
Received: by kulla.think.com; Mon, 9 Jan 89 02:26:26 EST
Date: Mon, 9 Jan 89 02:26:26 EST
From: barmar@Think.COM
Message-Id: <8901090726.AA09352@kulla.think.com>
To: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 7 Jan 89 11:48:52 MST <8901071848.AA08925@defun.utah.edu>
Subject: **DRAFT** issue CONSTANT-COLLAPSING
Here's my suggestion on how to define when constants may be collapsed.
It is based on a variant of the old railroad-track definition of EQ.
The general idea is that two objects may be collapsed into one object
unless there would have been a way to detect the difference between
the two original objects. In the case of ordinary objects consed at
runtime, this means that if there's a way to modify the contents of an
instance of a type then instances of that type may not be collapsed
(because modifying instance-1 would cause instance-2 to change).
If CONSTANT-MODIFICATION:DISALLOW is approved, then the above rule can
be used to derive a "coalescing predicate". Any two constants may be
collapsed if the results of all accessing operations on the objects
would produce collapsable results. These operations should include any
operations for accessing the contents of the object (CAR, CDR, AREF,
DEFSTRUCT-defined accessors, etc.), and functions for returning
attributes of the object (LENGTH, TYPE-OF, FILL-POINTER, etc.). I
believe that any EQUAL objects are collapsable under this definition,
so this more complex predicate need only be used when deciding whether
to collapse non-EQUAL objects.
barmar
∂08-Jan-89 2342 CL-Compiler-mailer **DRAFT** issue CONSTANT-COMPILABLE-TYPES
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 8 Jan 89 23:41:53 PST
Return-Path: <barmar@Think.COM>
Received: from kulla.think.com by Think.COM; Mon, 9 Jan 89 02:35:59 EST
Received: by kulla.think.com; Mon, 9 Jan 89 02:38:15 EST
Date: Mon, 9 Jan 89 02:38:15 EST
From: barmar@Think.COM
Message-Id: <8901090738.AA09372@kulla.think.com>
To: cl-compiler@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 7 Jan 89 11:47:31 MST <8901071847.AA08919@defun.utah.edu>
Subject: **DRAFT** issue CONSTANT-COMPILABLE-TYPES
The full extension of the concept of coalescing of constants is to say
that they can be coalesced exactly when they are similar as constants.
I guess my last message can be thought of as endorsing this idea.
barmar
∂09-Jan-89 0644 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 9 Jan 89 06:43:56 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa16505; 9 Jan 89 8:51 EST
Received: from draper.com by RELAY.CS.NET id ab22894; 9 Jan 89 8:40 EST
Date: Mon, 9 Jan 89 07:37 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Re: issue ALLOW-LOCAL-INLINE
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER,SEB1525
Concerning Masinter's comments...
Maybe we need a (DECLARE (OPTIMIZE (COMPILER-SPACE ...))) ???
∂09-Jan-89 0644 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 9 Jan 89 06:44:05 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa16627; 9 Jan 89 8:56 EST
Received: from draper.com by RELAY.CS.NET id ac22894; 9 Jan 89 8:41 EST
Date: Mon, 9 Jan 89 07:53 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER,SEB1525
From: IN%"sandra%defun@cs.utah.EDU" "Sandra J Loosemore" 6-JAN-1989 19:53
To: "Steve Bacher (Batchman)" <SEB1525@DRAPER.COM>
Subj: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
>> Many common uses of EVAL-WHEN would have different behavior. e.g.:
>> (eval-when (compile load eval)
>> (proclaim '(special foo)) ; make FOO special to compiler and in compiled code
>> (defun some-function (...) ...) ; make a function definition available, etc.
>> (define-setf-method ...) ; you get the idea by now...
>> ...
>> )
>
>Ummm, I'm not sure how taking away the top-level-ness of the body of
>the EVAL-WHEN would change the behavior of this example. Since the
>COMPILE situation causes the body to be evaluated as an explicit PROGN
>*before* any other normal compiler processing of the body, the
>PROCLAIM will still get evaluated at compile time, SOME-FUNCTION will
>be defined in at compile time, and the DEFINE-SETF-METHOD will be
>defined at compile time. Can you please clarify why you think this
>example would break?
Sure, those things would get evaluated at compile time. What I'm worried about
is the compiler's particular handling of those forms at top level - for example,
the compiler has to do magic things with PROCLAIM when it sees it at top level,
otherwise the proclamation won't work, right? In that case, if the compiler
doesn't think that there's a PROCLAIM at top level because it happens to have
been wrapped in an EVAL-WHEN, we can only lose, right? User-defined SETF
methods would have the same problem. The exhortations to users to wrap such
things in (eval-when (compile load eval) ...) would be inadequate. Users
might even have to do
(define-setf-method . lots-of-complicated-hair)
(eval-when (compile)
(define-setf-method . lots-of-complicated-hair)
; i.e. the same hair, duplicated
)
∂09-Jan-89 0742 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Jan 89 07:42:44 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA21867; Mon, 9 Jan 89 08:41:33 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA10009; Mon, 9 Jan 89 08:41:28 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901091541.AA10009@defun.utah.edu>
Date: Mon, 9 Jan 89 08:41:26 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: "Steve Bacher (Batchman)" <SEB1525@draper.com>, Mon, 9 Jan 89 07:53 EST
> Sure, those things would get evaluated at compile time. What I'm
> worried about is the compiler's particular handling of those forms at
> top level - for example, the compiler has to do magic things with
> PROCLAIM when it sees it at top level, otherwise the proclamation
> won't work, right?
There is nothing in CLtL that says that PROCLAIM has magic
compile-time behavior at top-level. We do have an issue around to
deal with this, but it's been tabled while we see what the sentiment
is for removing the magic behavior of the package functions. As
things stand now, for portable behavior you *must* wrap the PROCLAIM
in an EVAL-WHEN if you want it to affect compilation.
> In that case, if the compiler doesn't think that
> there's a PROCLAIM at top level because it happens to have been
> wrapped in an EVAL-WHEN, we can only lose, right?
Since the compiler has already evaluated the PROCLAIM because of the
COMPILE situation being specified to the EVAL-WHEN, why evaluate it
again? Why isn't it sufficient just to compile it normally?
> User-defined SETF
> methods would have the same problem. The exhortations to users to
> wrap such things in (eval-when (compile load eval) ...) would be
> inadequate. Users might even have to do
>
> (define-setf-method . lots-of-complicated-hair)
> (eval-when (compile)
> (define-setf-method . lots-of-complicated-hair)
> ; i.e. the same hair, duplicated
> )
I still don't understand what you think the problem would be. You'll
have to be much more specific about it -- provide an example and step
through it, describing exactly what will go wrong.
-Sandra
-------
∂09-Jan-89 1105 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Jan 89 11:05:02 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA29325; Mon, 9 Jan 89 12:03:28 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA10143; Mon, 9 Jan 89 12:03:17 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901091903.AA10143@defun.utah.edu>
Date: Mon, 9 Jan 89 12:03:15 MST
Subject: issue COMPILER-LET-CONFUSION, version 5
To: kmp@stony-brook.scrc.symbolics.com
Cc: cl-compiler@sail.stanford.edu
Here's my revised version. The major changes are to the discussion
section. Note that I've made a suggestion at the end for a possible
compromise position.
Further comments, flames etc. are welcome.
Issue: COMPILER-LET-CONFUSION
Forum: Compiler
References: CLtL p. 112
Category: CHANGE
Edit History: V1, 27 Sep 1988, Sandra Loosemore (initial version)
V2, 04 Oct 1988, Sandra Loosemore (add another example)
V3, 31 Oct 1988, Sandra Loosemore (only proposal ELIMINATE)
V4, 08 Jan 1989, Kent M. Pitman (new alternative)
V5, 09 Jan 1989, Sandra Loosemore (discussion)
Problem Description:
The description of the COMPILER-LET special form in CLtL is confusing
to many people. There are no examples provided to make it clear how it
is supposed to be used. The only description which is offered is overly
concrete, which have led to confusion about the intent of COMPILER-LET,
and about its implementability.
The intent of COMPILER-LET was to permit information to be communicated
between macros by use of dynamic variables at macroexpansion time.
It was not necessary to the intended uses of COMPILER-LET that such
variables ever be bound at execution time.
Unfortunately, probably because some implementations did not primitively
support COMPILER-LET at the time CLtL was written, an exception was
permitted to make COMPILER-LET `more or less work' in interpreters:
the COMPILER-LET variables were permitted to be bound at execution time.
The problem was further compounded by the fact that CLtL presented this
exception as part of COMPILER-LET's contract rather than as an
implementation note, and by the fact that no examples of actually using
COMPILER-LET correctly are provided.
Subtle bugs can be introduced because of the different handling of the
variable bindings in the interpreter and the compiler. In compiled
code, the bindings are only lexically visible during the expansion of
macros at compile time, while in interpreted code the bindings have
dynamic scope and may also be seen during ordinary evaluation if
evaluation and macroexpansion happen concurrently.
Further compatibility problems can result from the value forms being
evaluated in a null lexical environment in the compiler and the ordinary
lexical environment in the interpreter.
Background and Analysis:
It should be clear up front that COMPILER-LET is not computationally
essential. Most (if not all) uses of it can be rewritten using MACROLET.
A typical use of COMPILER-LET might be:
(defvar *local-type-declarations* '())
(defmacro local-type-declare (declarations &body forms)
`(compiler-let ((*local-type-declarations*
(append ',declarations *local-type-declarations*)))
,@forms))
(defmacro typed-var (var)
(let ((type (assoc var *local-type-declarations*)))
(if type `(the ,(cadr type) ,var) var)))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
The same thing could be accomplished using MACROLET:
(defmacro local-type-declare (declarations &body forms)
(local-type-declare-aux declarations forms))
(defmacro typed-var (var) var)
(eval-when (eval compile load)
(defun local-type-declare-aux (declarations forms)
`(macrolet ((typed-var (var)
(let ((type (assoc var ',declarations)))
(if type `(the ,(cadr type) ,var) var)))
(local-type-declare (new-declarations &body new-forms)
(local-type-declare-aux
(append new-declarations ',declarations)
new-forms)))
,@forms)))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
Opinion is divided as to which of the two is more understandable. Some
people find the COMPILER-LET idiom more understandable, while others
find it just as natural to use MACROLET.
The issues are these:
- Is it possible to implement COMPILER-LET in a usefully consistent
way in all implementations?
- Are the benefits of providing a useful and compatible implementation
of COMPILER-LET worth any associated cost?
Two proposals are presented below:
- Option REPAIR argues that COMPILER-LET provides interesting
functionality that can be implemented in a manner that is usefully
consistent across implementations, and that the associated cost
is low enough for it to be worthwhile to do so.
- Option ELIMINATE presents a fall-back position for those who
either find that COMPILER-LET is not possible to implement in
a usefully consistent way in all implementations, or for those who
agree that although technically possible to implement, the
functionality does not justify the additional complication to the
language.
Proposal (COMPILER-LET-CONFUSION:REPAIR):
Strike the existing definition of COMPILER-LET. Redefine it as follows:
COMPILER-LET [Special form]
COMPILER-LET is similar to LET, but it always makes special
bindings and makes those bindings visible only during
macroexpansion of forms in the body, not during the runtime
execution of those forms.
The intent is that some macros might macroexpand into calls to
COMPILER-LET in which the body would the contain references to
macros which access the variables in the COMPILER-LET.
The initial value forms of the bindings, if any, are always
evaluated in a null lexical context, regardless of whether the
COMPILER-LET expression is being interpreted or compiled.
The initial value forms of the bindings, if any, are evaluated in
a dynamic context where the bindings of any lexically enclosing
COMPILER-LET are visible, and where dynamic execution-time
environment may or may not be visible.
Implementation Note: Permitting the execution-time dynamic
environment to be visible when initializing COMPILER-LET variables
is a concession to some interpreters which may have to do this in
order to keep the cost down. Where feasible, implementors should
try not to make the runtime environment visible.
Rationale:
This gives a consistent description of COMPILER-LET which separates
issues of intent from those of implementation in a way that makes it
possible for portable code to make serious use of it, and which does
not force gratuitous incompatibilities between interpreters and
compilers.
This description of COMPILER-LET can be implemented without undue
cost by all implementations. See "Cost to Implementors" for details.
Cost to Implementors:
Modest, but nontrivial in some implementations.
In compiled code, and in interpreters doing a one-time semantic
prepass, it should be fairly easy for COMPILER-LET to cause the
variables to get bound (using PROGV) during semantic analysis.
In interpreters which do not do a semantic-prepass, it is necessary
to fully macroexpand the body. Assuming the presence of a
SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
could look like:
(DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
(SETQ BINDINGS ;; Assure no non-atom bindings
(MAPCAR #'(LAMBDA (BINDING)
(IF (ATOM BINDING) (LIST BINDING) BINDING))
BINDINGS))
(PROGV (MAPCAR #'CAR BINDINGS)
(MAPCAR #'CDR BINDINGS)
(SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))
This reduces the problem of writing a program capable of doing a
full macroexpansion. Many systems already have such a facility.
Pitman wrote such a facility in Cloe Runtime in order support
SYMBOL-MACROLET (before it was christened a special form); it was
about 750 lines of relatively straightforward, well-commented code.
Another approach, which has not been fully explored, but which seems
plausible, is for COMPILER-LET to annotate the environment with the
bindings, and then to instantiate the bindings for the duration of
each call to MACROEXPAND-1. To accommodate SETQ of COMPILER-LET
variables, some care would be needed to assure that assignments to
these variables were recorded at the end of such a binding context
in order to correctly affect subsequent macroexpansions in the same
COMPILER-LET scope. This technique might be slightly slower, but
could avoid the need for a special code-walker. Also, the slowness
would generally only be incurred when a COMPILER-LET was actually
being processed, which (depending on the application) might not be
the common case.
Cost to Users:
Code currently depending on this feature is either non-existent or
already not portable (due to wide variation in implementation
strategy for COMPILER-LET).
Most users will probably be happy for any interpretation which offers
them a future shot at portability.
Proposal (COMPILER-LET-CONFUSION:ELIMINATE):
Remove COMPILER-LET from the language.
Rationale:
Some people think that having one less special form would simplify the
language, and that the functionality provided by COMPILER-LET is not
worth the additional complication.
This is a fallback position for those who believe that COMPILER-LET
is not implementable in consistently useful way across implementations,
or for those who believe that a consistently useful implementation
would be prohibitively expensive.
Cost to Implementors:
Minimal. Implementations could continue to support COMPILER-LET as
an extension.
Cost to Users:
People who use COMPILER-LET would have to rewrite their programs to use
some other construct. As discussed above, most uses of COMPILER-LET
for communication between macros can be handled using MACROLET, though
some perspicuity may be lost in the process.
Current Practice:
Some implementations have implemented the description in CLtL.
Users of those implementations (quite reasonably) can't figure how to
use COMPILER-LET and so don't use it much.
Some implementations (the ones from which COMPILER-LET originally came)
continue to use their pre-CLtL semantics. These semantics are useful, though
incompatible with CLtL (which they largely consider to simply be in error).
Users of those implementations probably use COMPILER-LET somewhat more
often since it has an intelligible behavior, but their code is not portable
since it relies on behaviors which are either contrary to or not guaranteed
by CLtL.
Benefits:
Either way, a potential area of incompatibility between compiled and
interpreted code would be eliminated.
Either way, a potential area of portability trouble would be very
drastically reduced (in the case of the REPAIR option) or eliminated
(in the case of the ELIMINATE option).
Discussion:
Pitman strongly favors COMPILER-LET-CONFUSION:REPAIR. He argues
against the idea of using MACROLET instead of COMPILER-LET, saying:
This is a little misleading because it's like saying you can
do without LET given that you have FLET. You can, but you lose some things
in the process:
Just as rewriting a LET using FLET might slow your computation, so too
a rewrite of COMPILER-LET using MACROLET might slow things down. However,
compilation speed is generally not weighted as heavily as execution speed
by many people, so the loss of speed here may not be as important.
Just as rewriting a LET using FLET might obscure the simplicity of your
intent, so too rewriting COMPILER-LET using MACROLET might obscure your
intent. You'd probably get used to recognizing idioms if you used it often
enough. Certainly this would be true if you didn't have LET. However,
COMPILER-LET is used less often, so not having it would mean that the
code you wrote instead would be much harder to read because people
wouldn't have the necessary familiarity with the idioms involved and so
wouldn't always understand them.
Just as rewriting a LET using FLET is harder to do (if not impossible) in
the presence of side-effects to the LET variables, so too rewriting
COMPILER-LET in terms of MACROLET is harder to do (if not impossible) in
the presence of side-effects.
Sandra Loosemore responds:
The argument that using MACROLET is more inefficient than COMPILER-LET
is questionable. All of the suggested implementation techniques for
COMPILER-LET involve considerable overhead.
If COMPILER-LET were not part of the language, people wouldn't think in
terms of rewriting COMPILER-LETs as MACROLETs; instead, they'd think of
how to use MACROLET in the first place to solve their problems. This
is what people who now use implementations with broken COMPILER-LETs
already do. Since MACROLET is now used much more frequently than
COMPILER-LET, that argues that people are much more familiar with
MACROLET idioms than COMPILER-LET idioms.
Having macros side-effect variables bound by COMPILER-LET is probably
not a good idea in most situations anyway, since the order in which macros
are expanded or the number of times they are expanded is not guaranteed.
Of the three suggested implementation techniques for COMPILER-LET, the
first has the problem that a substantial number of users have expressed
dislike for interpreters which do a semantic prepass (because macros
cannot be redefined freely without re-evaluating the definitions of
all functions that call the macro). The second suggested technique
has the same problem but to a lesser extent (only function definitions
nested inside of COMPILER-LETs are affected).
The third suggested implementation technique seems questionable to me.
In particular, unless we place an addition restriction on macro
expansion environments captured with &environment to give them only
dynamic extent within the macro function (instead of the default
indefinite extent), then the dynamic binding of the COMPILER-LET
variables will have to be performed by MACROEXPAND-1 or by the macro
function itself, instead of by the interpreter. As an example of how
one might use environments with indefinite extent, consider the
following rewriting of the same example presented above:
(defmacro typed-var (var) var)
(defmacro local-type-declare (declarations &body forms &environment env)
`(macrolet ((typed-var (&whole w var)
(let ((type (assoc var ',declarations)))
(if type
`(the ,(cadr type) ,var)
(macroexpand w ',env)))))
,@forms))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
I am not violently opposed to the idea of retaining COMPILER-LET in
the language, but I would feel more comfortable with proposal REPAIR
if it allowed the special bindings made by COMPILER-LET to be visible
during normal evaluation. After all, the proposal already allows
bindings made by normal evaluation to be seen by the COMPILER-LET.
What's more, code that uses the same variables during normal evaluation
that are used by macro expander functions is suspect even if COMPILER-LET
is not involved, for example:
(defvar *foo* 'global-value)
(defmacro foo-macro () `',*foo*)
(let ((*foo* 'dynamic-value))
(foo-macro)) ==> ?????
I believe this restriction causes unnecessary hair for implementors
and doesn't buy anything for users. We'd be better off just coming
out and saying explicitly that the behavior is unspecified.
-------
∂09-Jan-89 1149 CL-Compiler-mailer Issue DEFINING-MACROS-NON-TOP-LEVEL, v5
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 9 Jan 89 11:46:13 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA15095; Mon, 9 Jan 89 11:47:41 PST
Received: from lukasiewicz.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA16666; Mon, 9 Jan 89 11:44:05 PST
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA07376; Mon, 9 Jan 89 11:46:32 PST
Date: Mon, 9 Jan 89 11:46:32 PST
From: jrose@Sun.COM (John Rose)
Message-Id: <8901091946.AA07376@lukasiewicz.sun.com>
To: IIM@ECLA.USC.EDU
Cc: cl-compiler@SAIL.STANFORD.EDU, iim@ECLA.USC.EDU
In-Reply-To: Kim A. Barrett's message of Sat 31 Dec 88 19:40:52-PST <12458958097.23.IIM@ECLA.USC.EDU>
Subject: Issue DEFINING-MACROS-NON-TOP-LEVEL, v5
Date: Sat 31 Dec 88 19:40:52-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Regarding the definition of top-level, a case can be made for macrolet not
pushing you from top-level to non-top-level. The argument is that you can take
a macrolet form, process the body to the extent of macroexpanding everything,
throw away the macrolet, and then process the body as a top-level progn. When
we (at IIM) worked out what our compiler's notion of top-level was going to be,
my boss argued us into implementing it this way. In general it turns out to be
a useful way to do things.
kab
-------
Yes, just last week I too found MACROLET very useful at top level, for
creating a number of related top-level forms, and using a macro to
factor out repeated structure among the forms. Here's an example:
(macrolet ((def-forwarded-to-head (acsor head-acsor)
`(defun ,acsor (x) (,head-acsor (person-head x)))))
(def-forwarded-to-head person-nose head-nose)
(def-forwarded-to-head person-mouse head-mouse)
(def-forwarded-to-head person-eye-1 head-eye-1)
...)
There's no reason to clutter up your Lisp world with a top-level
definition for DEF-FORWARDED-TO-HEAD. On the other hand, the
function definitions (of PERSON-NOSE, etc.) seem perfectly
top-level, as if defined by:
(defmacro def-forwarded-to-head (acsor head-acsor)
`(defun ,acsor (x) (,head-acsor (person-head x))))
(def-forwarded-to-head person-nose head-nose)
(def-forwarded-to-head person-mouse head-mouse)
(def-forwarded-to-head person-eye-1 head-eye-1)
...
(setf (macro-function 'def-forwarded-to-head) nil)
But the first rendering is cleaner. It doesn't disturb the set of
top-level macros.
-- John
∂09-Jan-89 1241 CL-Compiler-mailer Re: **DRAFT** issue CONSTANT-COLLAPSING
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Jan 89 12:40:48 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06433; 9 Jan 89 18:58 GMT
Date: Mon, 9 Jan 89 19:00:05 GMT
Message-Id: <11550.8901091900@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: **DRAFT** issue CONSTANT-COLLAPSING
To: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 7 Jan 89 11:48:52 MST
> Rationale:
>
> There is little reason why implementations should not be allowed to
> perform more general collapsing of structures, since the arguments
> against doing so also apply to collapsing of EQUAL structures, which
> is already permitted.
There's a problem with this rationale. Arguments against individual
cases might also apply to EQUAL structures, but an argument that there
should be *some* non-coalescable structures is different. I might
say, well, EQUAL sturctures is OK because I still have vectors, etc.
Removing all the alternatives requires more than arguments against
each one individually.
> Cost to users:
>
> It is hard to imagine a program that would break under this proposal.
As I've said before, I think it's trivial to imagine a program that
would break. Just think of one that assumes only EQUAL structures
will be collapsed.
-- Jeff
∂09-Jan-89 1321 CL-Compiler-mailer Issue: COMPILER-LET-CONFUSION (Version 6)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Jan 89 13:21:17 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 517896; Mon 9-Jan-89 15:35:24 EST
Date: Mon, 9 Jan 89 15:34 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COMPILER-LET-CONFUSION (Version 6)
To: sandra%defun@cs.utah.edu
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU
Message-ID: <890109153458.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
I agree this is looking better, but I think I might want to make a few
more changes [perhaps even add an option! -- see below] before sending
this out to X3J13. Rather than edit the proposal back and forth, I
though I'd just hit a few hot issues separately and see
what you think.
----------
...
Having macros side-effect variables bound by COMPILER-LET is probably
not a good idea in most situations anyway, since the order in which macros
are expanded or the number of times they are expanded is not guaranteed.
...
In some implementations, the order of processing might be well-defined
(as an extension), and so assignment might be useful in such implementations.
Consider that if processing were known to be left to right, it might want
to guarantee behavior such as the following:
(DEFMACRO WITH-FOO (VALUE &BODY FORMS)
`(COMPILER-LET ((*FOO-USED* NIL))
(MACROLET ((FOO ()
(DECLARE (SPECIAL *FOO-USED*))
(SETQ *FOO-USED* T)
'(LOCALLY (DECLARE (SPECIAL *FOO*)) *FOO*))
(COMPOSE-FOO-USER ()
(IF *FOO-USED*
`(LET ((*FOO* ,',VALUE))
(DECLARE (SPECIAL *FOO*))
(DO-IT))
`(DO-IT))))
(FLET ((DO-IT () ,@FORMS))
(COMPOSE-FOO-USER)))))
(LIST (SETQ X 1) (WITH-FOO (INCF X) (LIST X (FOO) (FOO))))
=> (1 (2 2 2))
(LIST (SETQ X 1) (WITH-FOO (INCF X) (LIST X (FOO))))
=> (1 (2 2))
(LIST (SETQ X 1) (WITH-FOO (INCF X) (LIST X)))
=> (1 (1))
Given our macroexpansion model, though, I think it's reasonable for us to
clarify that SETQ is forbidden for the sake of code portability. I couldn't
think of any non-trivial way to take advantage of SETQ given a non-left-to-right
expansion.
This will allow us to make some of the sections shorter since we needn't
get side-tracked talking about assignment.
...
I believe this restriction causes unnecessary hair for implementors
and doesn't buy anything for users. We'd be better off just coming
out and saying explicitly that the behavior is unspecified.
...
The example you cite is not the best for seeing the issue. It doesn't fix
a problem, but it makes it much less visible. The case of
interest is not relying on a program special variable from within a
macro, but rather having a COMPILER-LET variable visible from within
a macro that isn't part of the same lexical scope. For example:
If LOOP does
(COMPILER-LET ((*INSIDE-LOOP* T))
...expansion...)
and LOOP-FINISH does
(DEFMACRO LOOP-FINISH ()
(IF *INSIDE-LOOP*
`(GO LOOP::LOOP-FINISH)
(ERROR "You are not inside LOOP.")))
then your error message will be poor if you do
(LOOP ... (EVAL '(LOOP-FINISH)))
because *INSIDE-LOOP* might be T in the interpreter.
I admit the screw case is still there, but it's much harder to get to
this way. You can only get to it by doing the EVAL call within the body
of a macro or macrolet, so it's much more rare.
I also note that making LOOP always do MACROLET of LOOP-FINISH will
get around the problem reliably, but I point out that the expense may
be non-trivial if there are a zillion little macros that LOOP (or
whatever) needs to bind and that may never end up getting called.
COMPILER-LET is therefore more efficient for cases like this.
----------
The following interesting compromise situation occurred to me, though.
I'm still thinking about it, but I'll mention it just as an option and
maybe we can pursue it as an alternative if people like it...
Suppose that instead of referencing the value as a special, you had
an operator COMPILER-SYMBOL-VALUE to get its value. [That could be a
function, macro, or special form.] I wouldn't have a problem calling
a function to get this data because I still get to use the same basic
`shape' of code. Also, uses of COMPILER-LET are rare enough that a
bit of extra syntax is not overwhelming.
(DEFMACRO mac (...)
... (COMPILER-SYMBOL-VALUE name) ...)
(new-COMPILER-LET ((name val))
...)
I don't know how other supporters of COMPILER-LET would feel about this.
It looks ok to me, though.
I can't think of any implementations in which this would be prohibitively
expensive to implement.
----------
...
If COMPILER-LET were not part of the language, people wouldn't think in
terms of rewriting COMPILER-LETs as MACROLETs; instead, they'd think of
how to use MACROLET in the first place to solve their problems.
...
I disagree with this. By analogy, if LET didn't exist, people would think
in terms of using FLET to solve their problems. The problem is that people
don't think that way. People think in terms of containers (variables)
as places to put things, and procedures (functions) as things that do things.
They don't like to think of a container as being represented by a function
whose meaning is might be locally changed in some contexts. It's just not
natural. That doesn't mean there aren't people who can't think that way --
just that I think it varies a lot.
----------
The question about whether the extent of an &ENV argument is indefinite or
dynamic is interesting. Is there a cleanup to cover this? I agree that
CLtL is not technically ambiguous -- that is, I don't recall ever having seen
anything to make me assume it's dynamic -- but I've always assumed it anyway.
I think Genera implements it as dynamic. Is there any good reason to want
it to be otherwise? Is an issue on this topic perhaps warranted? We could
certainly make it be dynamic if people were going to use it, but if they're
not going to use it it seems a bit like needless overhead...
∂09-Jan-89 1430 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 6)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Jan 89 14:30:31 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA09874; Mon, 9 Jan 89 15:29:02 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA10554; Mon, 9 Jan 89 15:28:54 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901092228.AA10554@defun.utah.edu>
Date: Mon, 9 Jan 89 15:28:53 MST
Subject: Re: Issue: COMPILER-LET-CONFUSION (Version 6)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Mon, 9 Jan 89 15:34 EST
You raise some interesting points here....
I actually *can* think of one example where it's useful for a macro to
SETQ a special variable as a side effect -- when the variable is some
kind of a counter used to generate unique labels. I'd rather not forbid
SETQ'ing entirely, but it is something that has to be used with caution.
I agree, leaving out references to assignment would help simplify the
writeup.
> Suppose that instead of referencing the value as a special, you had
> an operator COMPILER-SYMBOL-VALUE to get its value. [That could be a
> function, macro, or special form.] I wouldn't have a problem calling
> a function to get this data because I still get to use the same basic
> `shape' of code. Also, uses of COMPILER-LET are rare enough that a
> bit of extra syntax is not overwhelming.
If you don't mind having to pass an explicit environment argument to
COMPILER-SYMBOL-VALUE (as you have to do for GET-SETF-METHOD, for
example), I think this bit of code will do what you want.
(defun compiler-symbol-value (symbol &optional env)
(macroexpand `(compiler-symbol-value-aux ,symbol) env))
(defmacro compiler-symbol-value-aux (symbol)
`(symbol-value ',symbol))
(defmacro compiler-let (var-value-pairs &body body &environment env)
(let ((bindings
(mapcar #'(lambda (v)
(if (symbolp v)
(cons v nil)
(cons (car v) (eval (cadr v)))))
var-value-pairs)))
`(macrolet ((compiler-symbol-value-aux (symbol)
(let ((info (assoc symbol ',bindings)))
(if info
(cdr info)
(compiler-symbol-value symbol ',env)))))
,@body)))
I wouldn't object greatly to adding this to the language, although
somebody is bound to ask why we should bother when it is something
that users can easily write for themselves if they need this
functionality.
> People think in terms of containers (variables)
> as places to put things, and procedures (functions) as things that do things.
> They don't like to think of a container as being represented by a function
> whose meaning is might be locally changed in some contexts. It's just not
> natural.
What I was suggesting is that some people might not formulate the
problem as having anything to do with a "container" in the first
place. Step back a bit and look at the bigger picture. The problem
the example in the writeup is trying to solve is providing a macro to
decorate variable references with type declarations within a
particular lexical scope. Actually, the most intuitive way I find to
think about this problem is the way that the new example I added to
the discussion section presents it (and the way I wrote the
COMPILER-LET macro above): first see if the variable matches those
that were supplied types in the innermost lexical scope, and if not
recurse on the next outermost lexical scope. Although you might find
it more intuitive to lump all the variable/type pairs into a
container, the container is not inherent in the solution to the
problem.
> The question about whether the extent of an &ENV argument is indefinite or
> dynamic is interesting. Is there a cleanup to cover this?
I don't think so. To me it seems more likely that some
implementations destructively bash on environment objects after you've
returned from the macro function, than that anybody is trying to
stack-allocate them. I think we do need to clarify this, along with
all the zillion other unresolved problems with environment objects. I
was hoping issue SYNTACTIC-ENVIRONMENT-ACCESS would help address some
of these problems but it's been languishing from neglect.
-Sandra
-------
∂09-Jan-89 1453 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 6)
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Jan 89 14:53:03 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa07833; 9 Jan 89 22:37 GMT
Date: Mon, 9 Jan 89 22:39:04 GMT
Message-Id: <12075.8901092239@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue: COMPILER-LET-CONFUSION (Version 6)
To: Kent M Pitman <KMP@scrc-stony-brook.arpa>,
sandra <@cs.utah.edu:sandra@defun>
In-Reply-To: Kent M Pitman's message of Mon, 9 Jan 89 15:34 EST
Cc: CL-Compiler@sail.stanford.edu
> The question about whether the extent of an &ENV argument is indefinite or
> dynamic is interesting. Is there a cleanup to cover this? I agree that
> CLtL is not technically ambiguous -- that is, I don't recall ever having seen
> anything to make me assume it's dynamic -- but I've always assumed it anyway.
> I think Genera implements it as dynamic. Is there any good reason to want
> it to be otherwise?
It is sometimes useful to be able to get the current macro env (for
code walkers, say), but if it has dynamic extent it's impossible to
return it.
I favor a cleanup issue, since it seems there is some doubt as to
what is required.
∂09-Jan-89 1551 CL-Compiler-mailer Re: issue DEFCONSTANT-SPECIAL
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Jan 89 15:49:47 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08520; 9 Jan 89 23:35 GMT
Date: Mon, 9 Jan 89 23:37:26 GMT
Message-Id: <12139.8901092337@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue DEFCONSTANT-SPECIAL
To: masinter.pa@xerox.com, cl-compiler@sail.stanford.edu
In-Reply-To: masinter.pa@com.xerox's message of 5 Jan 89 22:19 PST
Cc: masinter.pa@xerox.com
> I think the issue is: Is it legal to attempt to lexically rebind a variable
> that has been defined with DEFCONSTANT, as might be implied by the wording
> on p. 69, and the Proposal is No, it is not, and the Current Practice is
> "Most implementations don't allow this."
I think you have identified the true problem (that is: where it is
most possible to notice the difference). There may also be some minor
issues, such as whether SYMBOL-VALUE or SPECIAL-P (assuming there is
one) likes constants. Right now the definition of SYMBOL-VALUE
explicitly allows constants but explains that this is because
constants are variables that can't be changed. It may be useful to
clarify whether constants are actually special variables or some other
kind of global named value. If we pass PROCLAIM-LEXICAL, some other
kinds might actually exist.
∂09-Jan-89 1556 CL-Compiler-mailer Re: Issue COMPILER-DIAGNOSTICS, v7
Received: from ti.com by SAIL.Stanford.EDU with TCP; 9 Jan 89 15:55:59 PST
Received: by ti.com id AA01596; Mon, 9 Jan 89 17:54:50 CST
Received: from Kelvin by tilde id AA13639; Mon, 9 Jan 89 17:38:04 CST
Message-Id: <2809381220-11359105@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 9 Jan 89 17:40:20 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU
Subject: Re: Issue COMPILER-DIAGNOSTICS, v7
In-Reply-To: Msg of Wed, 4 Jan 89 23:15 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> btw, i've been thinking more about the lispm's NOTIFY and i'm starting to
> feel uncomfortable about using it as a model, and hence about using the
> names NOTIFY and NOTIFICATION.
I agree that this is not really relevant. The compiler messages we are
talking about are things you would want written to the window the
compiler is running in, rather than having them pop up on top of whatever
window is currently exposed.
∂09-Jan-89 1601 CL-Compiler-mailer Re: issues relating to compiled constants
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Jan 89 16:01:18 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08627; 9 Jan 89 23:52 GMT
Date: Mon, 9 Jan 89 23:54:15 GMT
Message-Id: <12210.8901092354@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issues relating to compiled constants
To: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 7 Jan 89 11:46:51 MST
It's good to have a list that summarizes the issues and how they
fit together.
> QUOTE-MAY-COPY
> May COMPILE and EVAL, as well as COMPILE-FILE, substitute
> equivalent copies of quoted objects?
Shouldn't we say it also determines whether other issues, such
as "compilable types" also apply to EVAL and COMPILE?
Cheers,
Jeff
∂09-Jan-89 1601 CL-Compiler-mailer agenda
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Jan 89 15:59:12 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA15122; Mon, 9 Jan 89 16:58:04 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA10661; Mon, 9 Jan 89 16:58:01 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901092358.AA10661@defun.utah.edu>
Date: Mon, 9 Jan 89 16:57:59 MST
Subject: agenda
To: cl-compiler@sail.stanford.edu
We're listed on the agenda for right after lunch on Monday afternoon.
At this point I am envisioning that the time we have allocated will be
spent in discussion of the issues that have been distributed.
Obviously, we won't be able to get into really detailed debates, since
we have many issues and little time, but I hope to at least be able to
clear up questions about the purpose and intent of the the various
issues.
I am getting a little discouraged in that a number of issues we have
had under discussion for some time seem to be getting no closer to
being "done". I understand from the schedule Kathy Chapman has sent
around that she would like to have pending issues cleared up no later
than the March meeting. Can we meet this deadline? I think it's
important that let everybody else know about how much we plan to have
done by then.
Does anybody think we need to have a subcommittee meeting? There is
not any time actually set aside for this on the agenda, but perhaps we
could set up something informal Sunday evening or during one of the
breaks later on in the week. (I'm going to be arriving Saturday
evening myself.)
-Sandra
-------
∂09-Jan-89 1637 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from ti.com by SAIL.Stanford.EDU with TCP; 9 Jan 89 16:37:07 PST
Received: by ti.com id AA01833; Mon, 9 Jan 89 18:36:34 CST
Received: from Kelvin by tilde id AA15134; Mon, 9 Jan 89 18:27:41 CST
Message-Id: <2809384201-11538228@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 9 Jan 89 18:30:01 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
In-Reply-To: Msg of Tue, 3 Jan 89 13:54:56 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Proposal: CONSTANT-CIRCULAR-COMPILATION:FLAG
>
> Add to the definition of Common Lisp a special variable:
>
> *DUMP-CIRCLE* [Special variable]
>
> State that if the (compile-time) value of *DUMP-CIRCLE* is NIL, it is
> an error for an object containing a circular reference to appear as a
> constant to be compiled. State that the compiler is required to
> preserve EQness of substructures within a file compiled with
> COMPILE-FILE when *DUMP-CIRCLE* is non-NIL.
But then someone would want to do something like
(COMPILER-LET ((*DUMP-CIRCLE* T))
(DEFUN FOO (...)
...
(... '#.(CIRCULAR-LIST ...) ...)...))
which raises some questions:
1. Is this flag still useful if COMPILER-LET is eliminated?
2. How much of the code does the COMPILER-LET have to surround in
order to be effective?
3. Is it even possible to control this during compilation? [In our
implementation, COMPILER-LET and (EVAL-WHEN (COMPILE) ...) both
happen only during pass 1, but the circularity would have to be
dealt with in the final output pass.]
Or would you say:
(EVAL-WHEN (COMPILE)
(UNLESS *DUMP-CIRCLE*
(ERROR "This file needs to be compiled with *DUMP-CIRCLE* true.")))
∂09-Jan-89 1658 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Jan 89 16:57:58 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA18155; Mon, 9 Jan 89 17:56:46 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA10710; Mon, 9 Jan 89 17:56:40 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901100056.AA10710@defun.utah.edu>
Date: Mon, 9 Jan 89 17:56:39 MST
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Mon, 9 Jan 89 18:30:01 CST
I guess I was envisioning that you would have to set *DUMP-CIRCLE* before
calling COMPILE-FILE, and that tweaking it during compilation probably
wouldn't do anything interesting. Cris?
-Sandra
-------
∂09-Jan-89 1706 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Jan 89 17:05:18 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08769; 10 Jan 89 0:19 GMT
Date: Tue, 10 Jan 89 00:20:32 GMT
Message-Id: <12283.8901100020@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue LOAD-TIME-EVAL
To: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Tue, 3 Jan 89 15:28:30 MST
> In interpreted code, (LOAD-TIME-VALUE <form>) is equivalent to (VALUES
> (EVAL (QUOTE <form>))).
Surely not, for this would cause all the QUOTE restructions to apply
if certain options of QUOTE-MAY-COPY were passed.
> Note that, in interpreted code, there is no guarantee as to when
> evaluation of <form> will take place, or the number of times the
> evaluation will be performed. Since successive evaluations of the
> same LOAD-TIME-VALUE expression may or may not result in an evaluation
> which returns a "fresh" object, destructive side-effects to the
> resulting object may or may not persist from one evaluation to the
> next.
This sort of defeates the purpose of :READ-ONLY-P NIL.
> It is safest to explicitly initialize the object returned by
> LOAD-TIME-VALUE, if it is later modified destructively.
I don't understand what this explicit initialization is or why it helps.
> Implementations must guarantee that each reference to a
> LOAD-TIME-VALUE expression results in at least one evaluation of its
> nested <form>. For example,
> (CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
> must perform two calls to COMPUTE-IT; although there is only one
> unique LOAD-TIME-VALUE expression, there are two distinct references
> to it.
Why do we want this restriction?
> The semantics of LOAD-TIME-VALUE would be simplified considerably if
> the READ-ONLY-P argument were removed and destructive operations on
> the result of evaluating <form> prohibited. However, some people feel
> that the ability to destructively modify the value is an essential
> feature to include.
You might cite reasons, even if only by a phrase or two. (I'm never
happy when all I'm told is that "some people think it's essential".)
I'm one of the people who would like to be able to modify values,
but I also want to be able to evade the QUOTE semantics for objects
in code without having to create a gensym to hold the value. So I
would be partially happy (whatever that means) even if the objects
were read-only (provided they weren't coalesced with other objects
-- and this matters even w/o the ability to modify because EQL can
still tell the difference, as can EQL hash tables). But objects
aren't like objects usually are if they can't be modified.
> Kent Pitman says:
> Although I'm willing to take multiple evaluation in the interpreter
> as a compromise position, I would like it mentioned in the discussion
> that this was only an expedient to getting this issue accepted at all,
> and that I'm not really happy about it. I have said that I think a
> number of our lingering problems (with EVAL-WHEN, COMPILER-LET, and
> this -- for example) are due to the presence of interpreters which do
> not do a semantic-prepass at a known time. If I had my way, we would
> require a semantic pre-pass and we would then be able to forbid
> multiple evaluations even in the interpreter.
I think Kent is right about the lingering problems, but I'm not sure
users would prefer the new behavior when debugging/modifying macros.
I don't think the implementation cost of a prepass is all that great.
∂09-Jan-89 1713 CL-Compiler-mailer Re: Issue CONSTANT-MODIFICATION, version 2
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Jan 89 17:12:48 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa00425; 10 Jan 89 1:00 GMT
Date: Tue, 10 Jan 89 00:39:18 GMT
Message-Id: <12372.8901100039@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue CONSTANT-MODIFICATION, version 2
To: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 7 Jan 89 10:33:56 MST
> Rationale:
>
> Disallowing modification of constants consistently in all situations,
> rather than just in compiled code, is proposed because in some
> compiled-only situations it may be difficult to distinguish between
> "compiled" and "interpreted" code.
But why can't constants be modified in compiled code? It seems clear
that they could be, so there must be some reasons why they aren't
always modifiable, and those are the real reasons.
∂09-Jan-89 1746 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 4)
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Jan 89 17:45:46 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa00696; 10 Jan 89 1:38 GMT
Date: Tue, 10 Jan 89 01:40:40 GMT
Message-Id: <12587.8901100140@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue: COMPILER-LET-CONFUSION (Version 4)
To: Kent M Pitman <KMP@scrc-stony-brook.arpa>,
sandra <@cs.utah.edu:sandra@defun>
In-Reply-To: Kent M Pitman's message of Sun, 8 Jan 89 17:58 EST
Cc: CL-Compiler@sail.stanford.edu
My main objection to COMPILER-LET -- that some implementations may
not fully macroexpand the body until after the dynamic extent of the
bindings has ended [Suppose a function is passed back. It might not
be expanded until called.] -- would be answered by the requirement
that the body be fully expanded.
> Current Practice:
>
> Some implementations have implemented the description in CLtL.
> Users of those implementations (quite reasonably) can't figure how to
> use COMPILER-LET and so don't use it much.
>
> Some implementations (the onces from which COMPILER-LET originally came)
> continue to use their pre-CLtL semantics. These semantics are useful, though
> incompatible with CLtL (which they largely consider to simply be in error).
> Users of those implementations probably use COMPILER-LET somewhat more
> often since it has an intelligible behavior, but their code is not portable
> since it relies on behaviors which are either contrary to or not guaranteed
> by CLtL.
I don't understand this section. What is this different semantics.
I've read the Symbolics documentation (some oldish versions) and can't
immediately see what it might be.
-- Jeff
∂09-Jan-89 1801 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Jan 89 18:00:32 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa00767; 10 Jan 89 1:48 GMT
Date: Tue, 10 Jan 89 01:50:39 GMT
Message-Id: <12615.8901100150@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue LOAD-TIME-EVAL
To: Jon L White <@sail.stanford.edu:jonl@lucid.com>,
sandra <@cs.utah.edu:sandra@defun>
In-Reply-To: Jon L White's message of Sat, 7 Jan 89 01:21:27 PST
Cc: cl-compiler@sail.stanford.edu, alarson@altura.honeywell.com
> At least one "wizard" at Lucid was thoroughly confused by the
> (CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
> example. Perhaps it needs to be fleshed out.
>
> I liked Aaron Larson's comment on the matter:
> "I was under the impression that the only loophole permitting the
> compiler to copy/substitute otherwise non EQ forms was with regard
> to QUOTE."
> That is, one might conceivable think of coalescing the two calls to
> LOAD-TIME-VALUE because of a sort of similarity to QUOTE.
I don't understand this remark. Aaron seems to be say that only
QUOTE allows EQ things to become non-EQ, and you seem to say that
only QUOTE allows non-EQ things to become EQ.
But as
> Aaron further noted, the compiler cannot reduce the calls to CONS
> in the structurally isomorphic form:
> (EQ #1=(CONS 'A 'B) #1#)
> So why should LOAD-TIME-VALUE be any different.
>
>
> Also your comment about constraints on the interpreter could be helpful:
> ". . . but it's not legitimate to cache LOAD-TIME-VALUE forms and
> resulting values and do a lookup based on EQness of source code
> expressions."
>
>
> -- JonL --
>
>
∂09-Jan-89 1810 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Jan 89 18:09:01 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa00811; 10 Jan 89 1:58 GMT
Date: Tue, 10 Jan 89 01:59:55 GMT
Message-Id: <12627.8901100159@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue LOAD-TIME-EVAL
To: Jon L White <jonl%lucid.com@NSS.Cs.Ucl.AC.UK>,
sandra <@cs.utah.edu:sandra@defun>
In-Reply-To: Jon L White's message of Sat, 7 Jan 89 01:21:27 PST
Cc: cl-compiler@sail.stanford.edu, alarson@altura.honeywell.com
> At least one "wizard" at Lucid was thoroughly confused by the
> (CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
> example. Perhaps it needs to be fleshed out.
>
> I liked Aaron Larson's comment on the matter:
> "I was under the impression that the only loophole permitting the
> compiler to copy/substitute otherwise non EQ forms was with regard
> to QUOTE."
> That is, one might conceivable think of coalescing the two calls to
> LOAD-TIME-VALUE because of a sort of similarity to QUOTE.
I started editing a reply to this and then decided I was wrong.
But my mailer mananged to send it anyway. (My fault really, but
I thought I had another chance to say "no".) Sorry.
But I still think this issue could be better explained. I never
thought that #= was guaranteed to work with code after the =, but I
did think it could say "put the same object here". So it might be
that something like (EQ '#1=(A B) '#1#) would work, or even -- using
self-evaluating objects -- (EQ #1="abc" #1). And LOAD-TIME-VALUE is
sort of like an object rather than an expression. So I think a
closer analogy may be to (EQ #1="abc" #1) rather than to
> (EQ #1=(CONS 'A 'B) #1#)
What I would like is a simple explanation that suggest any of this
reasoning.
∂09-Jan-89 1824 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Jan 89 18:23:48 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA20385; Mon, 9 Jan 89 19:22:39 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA10827; Mon, 9 Jan 89 19:22:34 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901100222.AA10827@defun.utah.edu>
Date: Mon, 9 Jan 89 19:22:31 MST
Subject: Re: issue LOAD-TIME-EVAL
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Tue, 10 Jan 89 00:20:32 GMT
> Date: Tue, 10 Jan 89 00:20:32 GMT
> From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
>
> > In interpreted code, (LOAD-TIME-VALUE <form>) is equivalent to (VALUES
> > (EVAL (QUOTE <form>))).
>
> Surely not, for this would cause all the QUOTE restructions to apply
> if certain options of QUOTE-MAY-COPY were passed.
Perhaps I can rephrase this. I seem to remember having tried once
before but apparently things got even more messed up in the process.
The idea is that evaluation takes place in a null lexical environment,
that it's performed by EVAL, and that exactly one value is returned.
> > Note that, in interpreted code, there is no guarantee as to when
> > evaluation of <form> will take place, or the number of times the
> > evaluation will be performed. Since successive evaluations of the
> > same LOAD-TIME-VALUE expression may or may not result in an evaluation
> > which returns a "fresh" object, destructive side-effects to the
> > resulting object may or may not persist from one evaluation to the
> > next.
>
> This sort of defeates the purpose of :READ-ONLY-P NIL.
I'm not sure exactly what problem you have here. :READ-ONLY-P NIL
says that it's OK to bash the object destructively, which is sometimes
useful even if such destructive side-effects are not persistent.
> I don't understand what this explicit initialization is or why it helps.
OK, here's an example. Suppose I have a function that requires a large
array for some temporary storage. There's really no need for it to
cons up a fresh array every time it's called, so I can use LOAD-TIME-VALUE
with :READ-ONLY-P NIL to say that it's OK only to cons up the array once.
However, there might still be garbage left in the array from one call to
another, so each time the function is called it would have to reinitialize
the array if it depends on it containing some particular values, instead
of just assuming that the array still contains whatever MAKE-ARRAY put into
it.
> > Implementations must guarantee that each reference to a
> > LOAD-TIME-VALUE expression results in at least one evaluation of its
> > nested <form>. For example,
> > (CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
> > must perform two calls to COMPUTE-IT; although there is only one
> > unique LOAD-TIME-VALUE expression, there are two distinct references
> > to it.
>
> Why do we want this restriction?
A previous paragraph says that it's OK to evaluate LOAD-TIME-VALUE forms
only once. This is to clarify what "only once" means -- once per
reference. As I already pointed out in response to somebody else's message
on this same point, it means that it's not a valid implementation
technique to cache LOAD-TIME-VALUE forms and resulting values and do a
lookup based on EQ source code.
As to why we want this restriction, it's to avoid problems due to
unexpected sharing of source code. This kind of sharing is
particularly likely to happen when LOAD-TIME-VALUE forms appear in the
expansion of a macro.
> You might cite reasons, even if only by a phrase or two. (I'm never
> happy when all I'm told is that "some people think it's essential".)
That particular phrase is Kent's. I've long ago given up on trying to
read Kent's mind :-), so he'll have to provide his own explanation.
> I think Kent is right about the lingering problems, but I'm not sure
> users would prefer the new behavior when debugging/modifying macros.
> I don't think the implementation cost of a prepass is all that great.
I agree with this -- the problems are cultural rather than technical.
People here at Utah who were initiated into the Lisp world by PSL
really retch at the thought of making a prepass a required part of the
language, because they view the ability to redefine macros on the fly
as an important feature (regardless of whether or not they actually
use the feature much in practice). Most people here are still using
HPCL-I, which does perform a prepass, and almost universally this is
the one misfeature they pick on most, even though the implementation
suffers from *far* more serious deficiencies (I stopped using it much
myself because it was so full of bugs).
-Sandra
-------
∂09-Jan-89 1829 CL-Compiler-mailer Re: Issue CONSTANT-MODIFICATION, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Jan 89 18:29:15 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA20415; Mon, 9 Jan 89 19:28:04 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA10839; Mon, 9 Jan 89 19:27:57 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901100227.AA10839@defun.utah.edu>
Date: Mon, 9 Jan 89 19:27:56 MST
Subject: Re: Issue CONSTANT-MODIFICATION, version 2
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Tue, 10 Jan 89 00:39:18 GMT
Re why constants in compiled code can't be modified:
Since "collapsing" of equivalent constants is allowed, destructively
modifying compiled constants can cause unintended side-effects to
other constants which just happen to look the same.
Many implementations already put constants in read-only storage. This
is actually write-protected in some implementations, and in others
it is simply not scanned by the garbage collector. Sometimes this is
done by the loader, and sometimes it's done during an image save or
other explicit compaction.
-Sandra
-------
∂09-Jan-89 1848 CL-Compiler-mailer **DRAFT** issue QUOTE-MAY-COPY
Received: from moon.src.honeywell.com (ALTURA.HONEYWELL.COM) by SAIL.Stanford.EDU with TCP; 9 Jan 89 18:48:18 PST
Return-Path: <alarson@src.honeywell.com>
Received: from pavo.SRC.Honeywell.COM
by moon.src.honeywell.com (5.59/smail2.6.3/06-17-88)
id AA11297; Mon, 9 Jan 89 20:46:43 CST
Posted-Date: Mon, 9 Jan 89 20:45:11 CST
Received: by pavo.src.honeywell.com (3.2/SMI-3.2)
id AA17180; Mon, 9 Jan 89 20:45:11 CST
Date: Mon, 9 Jan 89 20:45:11 CST
From: alarson@src.honeywell.com (Aaron Larson)
Message-Id: <8901100245.AA17180@pavo.src.honeywell.com>
To: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 7 Jan 89 11:49:24 MST <8901071849.AA08928@defun.utah.edu>
Subject: **DRAFT** issue QUOTE-MAY-COPY
I have several problems with this proposal, although I support what I
believe to be the intent of :ALWAYS.
This proposal brings up once again the ever present confusion between code
and data. I don't think that the lagnuage as defined in CLtL is adequate
to describe this problem. For example (from the proposal):
Change the description of QUOTE to indicate that (QUOTE <x>) returns
an object equivalent to <x>, which may or may not be EQ to <x>.
Likewise, a self-evaluating form may also return an equivalent copy
of the object.
...
If an implementation chooses to copy constants, the copying may only
happen once each time the form containing the constant is processed
with COMPILE or EVAL (see examples below). ...
I believe that QUOTE has to return THE argument it is given. Secondly
since CLtL describes the derivation of values from language constructs as
evaluation, it makes little sense to talk about "each time the form ... is
processed by eval" in any way that would allow repeated calls to the
function FOO to return EQ objects if QUOTE were permitted to copy its
argument each time it was "processed by EVAL"
(defun foo () '(a b c))
I think that some extra (conceptual) machinery is necessary. For example,
lets suppose that the language was changed as follows:
EVAL only works on code, not data,
there exists a function called PROMOTE that converts data into code.
(I'm not acutally advocating that we change the language, just a thought
experiment). We would now talk about READ PROMOTE EVAL PRINT loops. If
there existed machinery like this in the language, then the statement of
this problem becomes trivial: "Is PROMOTE permitted to copy its argument?"
COMPILE, and COMPILE-FILE could either be defined to be synonyms for
PROMOTE, or required to take PROMOTEd arguments. Similarly PROMOTE would
be permitted to collapse EQUAL parts of its substructure if it so desired.
If PROMOTE were permitted to copy its argument, then part of the confusion
in the example in the statement of the proposal LOAD-TIME-EVAL (recall "(eq
#1=stuff #1#)") would also be eliminated because it no longer makes sense
to talk about shared structure in CODE.
Perhaps only things that can be reliably put in object files should be
permitted to be PROMOTEd (e.g. only those things wich are "equivalent as
constants" or some such verbiage), even if that does not include circular
structures.
∂09-Jan-89 1902 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Jan 89 19:01:46 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA20679; Mon, 9 Jan 89 19:59:38 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA10894; Mon, 9 Jan 89 19:59:26 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901100259.AA10894@defun.utah.edu>
Date: Mon, 9 Jan 89 19:59:25 MST
Subject: Re: **DRAFT** issue QUOTE-MAY-COPY
To: alarson@src.honeywell.com (Aaron Larson)
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: alarson@src.honeywell.com (Aaron Larson), Mon, 9 Jan 89 20:45:11 CST
Thank you for your comments. A similar idea did crop up a while back
in one of our internal discussions on this issue -- that any copying
is performed when the random list representing a program is promoted
into a real program by evaluation or compilation -- but it kind of got
lost in the shuffle.
I'm not so sure that we really need to talk about whether it is
legitimate for entire programs to be copied, at least for this issue.
An alternate way of looking at the problem we're trying to resolve
here is whether a constants in a program must be EQL to the objects in
the source code for that program that happen to represent those
constants.
-Sandra
-------
∂09-Jan-89 2018 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 9 Jan 89 20:18:22 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01635g; Mon, 9 Jan 89 20:12:46 PST
Received: by bhopal id AA12006g; Mon, 9 Jan 89 20:14:56 PST
Date: Mon, 9 Jan 89 20:14:56 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901100414.AA12006@bhopal>
To: sandra%defun@cs.utah.edu
Cc: SEB1525@draper.com, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Sandra J Loosemore's message of Sun, 8 Jan 89 11:17:03 MST <8901081817.AA09469@defun.utah.edu>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
re: (eval-when (eval compile load)
(defmacro bar ...))
Suppose we do as you suggest and say that the bodies of top-level
EVAL-WHENs continue to be top-level, but prevent nested EVAL-WHENs
from doing COMPILE evaluation. Then, since the macro definition for
BAR is at top-level, it must cause some compile-time magic to happen
when it is compiled (processing for the LOAD situation). This implies
that you couldn't implement DEFMACRO by expanding it into an EVAL-WHEN,
because the required magic actions would be suppressed.
Say, didn't you realize that the COMPILE situation in the outter eval-when
means that the DEFMACRO will be evaluated at compile time, regardless of
any nested inner eval-when's? You know that I favor an implementaiton
of DEFMACRO that simply macroexpands onto usages of EVAL-WHEN, so that
there is only *one* notion of toplevel "magic" --namlely eval-when.
-- JonL --
∂09-Jan-89 2024 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 9 Jan 89 20:24:17 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01642g; Mon, 9 Jan 89 20:19:03 PST
Received: by bhopal id AA12022g; Mon, 9 Jan 89 20:21:18 PST
Date: Mon, 9 Jan 89 20:21:18 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901100421.AA12022@bhopal>
To: sandra%defun@cs.utah.edu
Cc: SEB1525@draper.com, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Sandra J Loosemore's message of Sun, 8 Jan 89 11:17:03 MST <8901081817.AA09469@defun.utah.edu>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Uh, I forgot to remind you that my position is not to "delete" the inner
COMPILE situations, but rather to resort to the overriding macrolet'd
definition for EVAL-WHEN [which effectively treats inner COMPILE
situations as EVAL situations.] That is, the inner form is certainly
evaluated, but only once! Inner forms like eval-when(eval compile)
would be evaluated twice if you don't do something special; and that
double evaluation is what I claim is wrong.
-- JonL --
∂09-Jan-89 2102 CL-Compiler-mailer Issue: COMPILER-LET-CONFUSION (Version 4)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 9 Jan 89 20:44:46 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01655g; Mon, 9 Jan 89 20:40:16 PST
Received: by bhopal id AA12056g; Mon, 9 Jan 89 20:42:31 PST
Date: Mon, 9 Jan 89 20:42:31 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901100442.AA12056@bhopal>
To: sandra%defun@cs.utah.edu
Cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, sandra%defun@cs.utah.edu,
CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: Sandra J Loosemore's message of Sun, 8 Jan 89 21:09:35 MST <8901090409.AA09741@defun.utah.edu>
Subject: Issue: COMPILER-LET-CONFUSION (Version 4)
I agree will all of your criticisms here; in particular:
-- Kent's argumentations belongs in the discussion section rather than
in the problem statement (well, at least they are intended to be
technical argumentations rather than testimonials, I think.)
-- "Both MACROLET and COMPILER-LET are fairly advanced features." -- yes,
and both can wind up being much more opaque than global definitions.
The argument _for_ COMPILER-LET should not be based upon the false
analogy of replacing LET with FLET, but rather on the replacement
of "local" facilities by "global" ones (but I suspect the case might
be a little weaker).
-- JonL --
∂09-Jan-89 2135 CL-Compiler-mailer cl-compiler issues online?
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 9 Jan 89 21:35:34 PST
Received: from Semillon.ms by ArpaGateway.ms ; 09 JAN 89 21:32:34 PST
Date: 9 Jan 89 21:31 PST
From: masinter.pa@Xerox.COM
Subject: cl-compiler issues online?
To: cl-compiler@sail.stanford.edu
cc: masinter.pa@Xerox.COM
Message-ID: <890109-213234-5430@Xerox>
Can we have the pending/passed cl-compiler issues in a public-access FTP
directory too?
I haven't been good about keeping the latest versions online; if you have
them but don't have a directory, I could put them on arisia.xerox.com too
along with the cleanup issues.
What do you say?
∂09-Jan-89 2214 CL-Compiler-mailer Issue DEFINING-MACROS-NON-TOP-LEVEL, v5
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 9 Jan 89 22:13:57 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01701g; Mon, 9 Jan 89 22:09:39 PST
Received: by bhopal id AA12225g; Mon, 9 Jan 89 22:11:52 PST
Date: Mon, 9 Jan 89 22:11:52 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901100611.AA12225@bhopal>
To: jrose@Sun.COM
Cc: IIM@ECLA.USC.EDU, cl-compiler@SAIL.STANFORD.EDU, iim@ECLA.USC.EDU
In-Reply-To: John Rose's message of Mon, 9 Jan 89 11:46:32 PST <8901091946.AA07376@lukasiewicz.sun.com>
Subject: Issue DEFINING-MACROS-NON-TOP-LEVEL, v5
re: Yes, just last week I too found MACROLET very useful at top level, for
creating a number of related top-level forms, and using a macro to
factor out repeated structure among the forms. Here's an example:
(macrolet ((def-forwarded-to-head (acsor head-acsor)
`(defun ,acsor (x) (,head-acsor (person-head x)))))
(def-forwarded-to-head person-nose head-nose)
(def-forwarded-to-head person-mouse head-mouse)
(def-forwarded-to-head person-eye-1 head-eye-1)
...)
This works in Lucid Common Lisp, even though MACROLET doesn't "pass
toplevel thru", because Lucid already allows defining macros at non
toplevel positions [however, there is some debugging information lost
in such cases -- I hope this bug is fixed in the next release].
-- JonL --
∂09-Jan-89 2304 CL-Compiler-mailer agenda
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 9 Jan 89 23:04:29 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01744g; Mon, 9 Jan 89 23:00:27 PST
Received: by bhopal id AA12360g; Mon, 9 Jan 89 23:02:38 PST
Date: Mon, 9 Jan 89 23:02:38 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901100702.AA12360@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Mon, 9 Jan 89 16:57:59 MST <8901092358.AA10661@defun.utah.edu>
Subject: agenda
Could I suggest that we merge with the Cleanup subcommittee, and plan
one big cleanup/compiler meeting on Sunday evening? And rather than
spending time rehashing technical discussions, I would think that we
could best spend that time reviewing which issues have an ICCIG(*) of
being accepted by a plenary vote.
I am definitely against trying to bring issues to a vote that are either
unstable in subcommittee (i.e., we keep changing our minds day by day)
or for which we know there is serious opposition that will effectively
stymie any voting.
-- JonL --
(*) Ice Cube's Chance In Gehenna.
∂10-Jan-89 0005 CL-Compiler-mailer Re: issue DEFCONSTANT-SPECIAL
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 10 Jan 89 00:05:39 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 10 JAN 89 00:03:30 PST
Date: 10 Jan 89 00:02 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue DEFCONSTANT-SPECIAL
In-reply-to: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>'s
message of Mon, 9 Jan 89 23:37:26 GMT
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
cc: masinter.pa@Xerox.COM, cl-compiler@sail.stanford.edu
Message-ID: <890110-000330-5576@Xerox>
I'd forgotten about SYMBOL-VALUE; if we add SPECIAL-P or some such, its
interaction with constants should be made explicit.
I guess I'd say that no, DEFCONSTANT doesn't declare it special, but
SYMBOL-VALUE works on special variables and constants, and that any
"special-variable-p" should return false.
I think this is compatible with PROCLAIM-LEXICAL: I think of a constant as
a non-SETFable kind of global lexical.
∂10-Jan-89 0054 CL-Compiler-mailer Issue CONSTANT-MODIFICATION, version 2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 10 Jan 89 00:54:12 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01807g; Tue, 10 Jan 89 00:50:08 PST
Received: by bhopal id AA12519g; Tue, 10 Jan 89 00:52:23 PST
Date: Tue, 10 Jan 89 00:52:23 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901100852.AA12519@bhopal>
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton's message of Tue, 10 Jan 89 00:39:18 GMT <12372.8901100039@subnode.aiai.ed.ac.uk>
Subject: Issue CONSTANT-MODIFICATION, version 2
re: But why can't constants be modified in compiled code? It seems clear
that they could be, so there must be some reasons why they aren't
always modifiable, and those are the real reasons.
There's the implementational reason, as verified by the "current practice"
of several widespread implementations (I see Sandra invoked this reason
in her reply). There's also a semantic consistency reason -- "constants"
should be constant, and not simply global parameters subject to casual
alteration during the running of the program. Remember the "Indiana rule"
(setn pi 3.0)
-- JonL --
P.S., No typo! -- Interlisp has the SETN operator even though CL doesn't
∂10-Jan-89 0109 CL-Compiler-mailer issue LOAD-TIME-EVAL
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 10 Jan 89 01:09:08 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01822g; Tue, 10 Jan 89 01:04:58 PST
Received: by bhopal id AA12540g; Tue, 10 Jan 89 01:07:15 PST
Date: Tue, 10 Jan 89 01:07:15 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901100907.AA12540@bhopal>
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Cc: @sail.stanford.edu:jonl@lucid.com, @cs.utah.edu:sandra@defun,
cl-compiler@sail.stanford.edu, alarson@altura.honeywell.com
In-Reply-To: Jeff Dalton's message of Tue, 10 Jan 89 01:50:39 GMT <12615.8901100150@subnode.aiai.ed.ac.uk>
Subject: issue LOAD-TIME-EVAL
re: I don't understand this remark. Aaron seems to be say that only
QUOTE allows EQ things to become non-EQ, and you seem to say that
only QUOTE allows non-EQ things to become EQ.
Consider the program:
(EQ (QUOTE (a b c)) (QUOTE (a b c)))
the two "sub-programs" which are both written as
(QUOTE (a b c))
are surely not EQ. But the compiler is licensed to "coalesce" the
two non-EQ constants into one "EQ" one, almost as if the user had
written instead:
(EQ #1=(QUOTE (a b c)) #1#)
I think that is what Aaron is referring to. And I enlarged upon it
to point out that even when the programs are "eq" -- as in
(EQ #1=(CONS 'A 'B) #1#)
the compiler cannot reduce this to one result. The reduction is
permitted only as a special case on QUOTE (and, if we worked on it,
it would be permitted on any stateless, side-effect-free function).
-- JonL --
∂10-Jan-89 0127 CL-Compiler-mailer Issue CONSTANT-MODIFICATION, version 2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 10 Jan 89 01:26:29 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01831g; Tue, 10 Jan 89 01:21:26 PST
Received: by bhopal id AA12564g; Tue, 10 Jan 89 01:23:43 PST
Date: Tue, 10 Jan 89 01:23:43 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901100923.AA12564@bhopal>
To: sandra%defun@cs.utah.edu
Cc: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK, cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Mon, 9 Jan 89 19:27:56 MST <8901100227.AA10839@defun.utah.edu>
Subject: Issue CONSTANT-MODIFICATION, version 2
[Sigh, apologies in advance. Pun coming up.]
This has got to be the cleanup issue of the year! Ever since we started
tinkering with the semantics of constants -- with "compiled constants" --
this proposal has been under CONSTANT MODIFICATION. Let's hope it has a
fixed point, and that we reach it soon.
-- JonL --
∂10-Jan-89 0404 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 10 Jan 89 04:04:31 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01871g; Tue, 10 Jan 89 04:00:31 PST
Received: by bhopal id AA12778g; Tue, 10 Jan 89 04:02:47 PST
Date: Tue, 10 Jan 89 04:02:47 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901101202.AA12778@bhopal>
To: masinter.pa@Xerox.COM
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM's message of 5 Jan 89 21:33 PST <890105-213421-186@Xerox>
Subject: issue SHARP-COMMA-CONFUSION
re: Actually, I think this is bogus. The simple portable way to handle #, is to
have the compiler use a a readtable which has ' defined as a readmacro like
Although several others have expressed an opion disagreeing with your
conjectured parallels between #, and #., I don't think anyone attempted
to rebut this suggestion adequately.
A couple months ago, there was extensive discussion about the inherently
ill-defined nature of #, but I can't seem to locate it in my mail file.
I sent out a couple of examples that would "break" in every Lisp I had
access to, either interpreted or compiled. [If anyone still has a
copy of that code, I would appreciate a copy sent back! blame it on
NFS or Emacs dying at the wrong time, but I have lost my copy].
The problem lies in thinking -- as you are in the above suggestion --
that when compiling a file, a form will be read solely for the purpose of
converting it into executable code of some form. Of course, a great deal
of what is read at compile time is for exectution (read: evaluation by the
interpreter) also. Thus you cannot tinker with the definition of ' in the
"compiler's readtable". [Well, you _could_ muck with it if the semantics
of QUOTE were clearly in the MAY-COPY:ALWAYS category, for then the
interpreter would simply pre-process any quoted forms, removing any
extraneous wrappers in the returned copy].
-- JonL --
∂10-Jan-89 0520 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 10 Jan 89 05:20:27 PST
Received: from relay2.cs.net by RELAY.CS.NET id ad08131; 10 Jan 89 8:02 EST
Received: from draper.com by RELAY.CS.NET id aa02366; 10 Jan 89 7:44 EST
Return-path: seb1525@mvs.draper.com
Received: from MVS.DRAPER.COM by DRAPER.COM via TCP; Tue Jan 10 07:41 EST
Received: by MVS.DRAPER.COM with NETMAIL; MON, 9 JAN 89 07:43 EST
Date: TUE, 10 JAN 89 07:42 EST
From: SEB1525@mvs.draper.com
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Sandra J Loosemore <sandra%defun@cs.utah.EDU>
X-MVS-to: CL-COMPILER@SAIL.STANFORD.EDU
X-send-dataset: 'XMAILMSG.SEB1525.XMA0901.T1007422.TEXT'
Message-Id: <NETMAILR09011007422SEB1525@MVS.DRAPER.COM>
Suppose you want to tell the compiler that your code is to be
compiled with variable FOO special, but you don't want to make
FOO special in the compiler's environment? How do you do it
under your EVAL-WHEN model using PROCLAIM?
I can't really illustrate the perceived problem with defining SETF
methods to the compiler, but it seems to me that if the issues
pertaining to the treatment of PROCLAIM and the package functions
at top level haven't been ironed out yet, it may be a bit premature
to change EVAL-WHEN so drastically. Presumably there's some
combination of proposals that will make everything work, but I'm
undoubtedly too muddle-headed at this time to figure it out.
Still, I'd sure like to see what it will be so that I can adjust
my implementation accordingly (since I haven't implemented most
of the "magic-to-the-compiler" things, I have a clean slate that
can be filled up the right way).
-------
∂10-Jan-89 0752 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Jan 89 07:51:24 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA01091; Tue, 10 Jan 89 08:49:32 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA11362; Tue, 10 Jan 89 08:49:26 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901101549.AA11362@defun.utah.edu>
Date: Tue, 10 Jan 89 08:49:24 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: Jon L White <jonl@lucid.com>
Cc: sandra%defun@cs.utah.edu, SEB1525@draper.com,
cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Jon L White <jonl@lucid.com>, Mon, 9 Jan 89 20:14:56 PST
> Date: Mon, 9 Jan 89 20:14:56 PST
> From: Jon L White <jonl@lucid.com>
>
> Say, didn't you realize that the COMPILE situation in the outter eval-when
> means that the DEFMACRO will be evaluated at compile time, regardless of
> any nested inner eval-when's? You know that I favor an implementaiton
> of DEFMACRO that simply macroexpands onto usages of EVAL-WHEN, so that
> there is only *one* notion of toplevel "magic" --namlely eval-when.
Yes, of course I realized that. That's why I've been arguing that
EVAL-WHEN does -not- need to pass top-level-ness on to its subforms --
so that EVAL-WHEN and the defining macros will be *defined* to have
the same behavior re multiple compile-time evaluations when nested
inside of an (EVAL-WHEN (COMPILE LOAD) ...).
If you'll please look at issue DEFINING-MACROS-NON-TOP-LEVEL, it is
not a requirement that defining macros expand into EVAL-WHENs.
(Pitman and others have argued strongly against even *recommending*
this.) What it does require is that the defining macros perform their
compile-time side effects **only when they appear at top-level**.
If we change the requirements for when EVAL-WHEN does compile-time
magic without changing the requirements for defining macros, then
using EVAL-WHEN to implement the defining macros would not be a
legitimate implementation technique.
Changing the definition of what top-level is will take care of the the
EVAL-WHEN problem and will also allow you to implement the defining macros
in terms of EVAL-WHEN.
The only other thing that top-level-ness implies is the order of
processing of subforms. So far, nobody has been able to come up with
an example that will break for this reason.
-Sandra
-------
∂10-Jan-89 0755 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Jan 89 07:55:30 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA01144; Tue, 10 Jan 89 08:53:58 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA11381; Tue, 10 Jan 89 08:53:53 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901101553.AA11381@defun.utah.edu>
Date: Tue, 10 Jan 89 08:53:51 MST
Subject: Re: issue SHARP-COMMA-CONFUSION
To: Jon L White <jonl@lucid.com>
Cc: masinter.pa@Xerox.COM, cl-compiler@sail.stanford.edu
In-Reply-To: Jon L White <jonl@lucid.com>, Tue, 10 Jan 89 04:02:47 PST
I think this is the piece of code you were referring to:
;;;--------------------------------------------------------------------------
(in-package "USER")
;;; Clean the slate, in case this isn't "first time" processing
(eval-when (eval compile load)
(fmakunbound 'expose)
(fmakunbound 'exposure-normality)
(proclaim '(special markers))
)
;;; Use different marker depending on which situation is relevant.
(eval-when (eval)
(setq markers '((eval a) (eval b) (eval c)))
)
(eval-when (compile)
(setq markers '((compile a) (compile b) (compile c)))
)
(eval-when (load)
(setq markers '((load a) (load b) (load c)))
)
(eval-when (eval compile load)
(defun expose ()
`(#,(pop markers) #,(pop markers)))
(defmacro exposure-normality ()
(if (member (car (expose))
'((eval a) (compile a) (load a))
:test #'equal)
`'normal
`'abnormal))
)
(eval-when (eval compile load)
(defparameter foo (expose))
(defparameter bar (exposure-normality))
)
;;;--------------------------------------------------------------------------
-------
∂10-Jan-89 0812 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Jan 89 08:12:01 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA01624; Tue, 10 Jan 89 09:10:53 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA11396; Tue, 10 Jan 89 09:10:48 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901101610.AA11396@defun.utah.edu>
Date: Tue, 10 Jan 89 09:10:47 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
To: SEB1525@mvs.draper.com
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: SEB1525@mvs.draper.com, TUE, 10 JAN 89 07:42 EST
> Date: TUE, 10 JAN 89 07:42 EST
> From: SEB1525@mvs.draper.com
>
> Suppose you want to tell the compiler that your code is to be
> compiled with variable FOO special, but you don't want to make
> FOO special in the compiler's environment? How do you do it
> under your EVAL-WHEN model using PROCLAIM?
Generally speaking, you can't. Note that some implementations that
treat top-level calls to proclaim specially also have it side-effect
the compiler's environment instead of only affecting the code being
compiled.
> it seems to me that if the issues
> pertaining to the treatment of PROCLAIM and the package functions
> at top level haven't been ironed out yet, it may be a bit premature
> to change EVAL-WHEN so drastically.
I don't think there's really much relationship between EVAL-WHEN and
the package functions and PROCLAIM. Speaking for myself here and not
all the other compiler folk, I would like to see a DEFPROCLAIM macro
introduced to take care of PROCLAIM, and the magic compile-time
behavior of the package functions removed and a macro introduced to
set up the package environment correctly. This would mean that there
would never be any need for compilers to treat any function calls
specially at top-level.
-Sandra
-------
∂10-Jan-89 1018 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 10 Jan 89 10:18:16 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA06516; Tue, 10 Jan 89 10:20:02 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA25251; Tue, 10 Jan 89 10:16:20 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA13697; Tue, 10 Jan 89 10:17:22 PST
Date: Tue, 10 Jan 89 10:17:22 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901101817.AA13697@clam.sun.com>
To: sandra%defun@cs.utah.edu
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Cc: cl-compiler@sail.stanford.edu
I guess I was envisioning that you would have to set *DUMP-CIRCLE* before
calling COMPILE-FILE, and that tweaking it during compilation probably
wouldn't do anything interesting. Cris?
-Sandra
-------
David Gray makes in interesting point in my opinion. My thinking has
been more like yours, but on second thought, it is more appropriate
for the source file to specify the value of *dump-circle* rather than
some operation.
Regardless of the disposition of COMPILER-LET, I think the proposal had
better also say that *dump-circle* is rebound to its current value at least
during COMPILE-FILE. That way a source file can (eval-when (compile)
(setq *dump-circle* t)) if it contains circular structure.
-Cris
∂10-Jan-89 1028 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Jan 89 10:27:51 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA07520; Tue, 10 Jan 89 11:26:30 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA11549; Tue, 10 Jan 89 11:26:25 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901101826.AA11549@defun.utah.edu>
Date: Tue, 10 Jan 89 11:26:23 MST
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: cperdue@Sun.COM (Cris Perdue)
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: cperdue@Sun.COM (Cris Perdue), Tue, 10 Jan 89 10:17:22 PST
I really dislike the idea of allowing it to be meaningful to tweak
this variable on the fly during compilation. I mean, I already
dislike the idea of adding the flag, but this is just too much. In a
multipass compiler, dumping of constants may not happen until much
later than the processing of EVAL-WHEN forms. For example, you might
not even look at constants until you've read in the code from the
entire file and performed the required processing on top-level-forms.
Plus, what happens if you try to coalesce a constant in created one
place where *DUMP-CIRCLE* was true with one that was created in
another place where *DUMP-CIRCLE* was false?
-Sandra
-------
∂10-Jan-89 1117 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 10 Jan 89 11:16:04 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06969; 10 Jan 89 18:42 GMT
Date: Tue, 10 Jan 89 18:44:32 GMT
Message-Id: <15199.8901101844@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: **DRAFT** issue QUOTE-MAY-COPY
To: Aaron Larson <alarson@altura.honeywell.com>, cl-compiler@sail.stanford.edu
In-Reply-To: Aaron Larson's message of Mon, 9 Jan 89 20:45:11 CST
> I believe that QUOTE has to return THE argument it is given.
There is a continuing problem with the language of this proposal.
I think the way we're being asked to think (by JonL and others)
is more or less equivalent to saying that QUOTE returns what it's
given, but what it's given may be a copy of the object that was
in the expression before EVAL ever saw it. For example,
(let ((a <expr>))
(eql a (eval `(quote (quote ,a)))))
might return NIL. It seems that you are thinking along similar lines,
as was Sandra:
From: sandra <(Sandra J Loosemore)sandra%defun@edu.utah.cs>
Date: Sat, 17 Dec 88 14:58:05 MST
Subject: Re: issue QUOTE-MAY-COPY, version 2
I'm not real sure if this line of thought is turning out to be
particularly productive. To me it seems pretty clear that any copying
of constants that goes on happens as a result of transforming an
arbitrary data structure into a program. In other words, the list
(defun foo () '(a b c))
is just a list. It doesn't become a program until it is passed to
EVAL or COMPILE or if it appears in a file being compiled with
COMPILE-FILE. The question we are trying to resolve is whether pieces
of the data structure that represent constant objects must appear
literally in the resulting program, or whether the transformation may
construct a equivalent copies instead.
Perhaps I chose a misleading name for this issue. I don't think
anybody is arguing that QUOTE itself must do whatever copying is
allowed. We could rename the issue to something less confusing, if
anybody has a suggestion.
-Sandra
> since CLtL describes the derivation of values from language constructs as
> evaluation, it makes little sense to talk about "each time the form ... is
> processed by eval" in any way that would allow repeated calls to the
> function FOO to return EQ objects if QUOTE were permitted to copy its
> argument each time it was "processed by EVAL"
I'm inclined to agree, but I think the problem is not so much that
we've confused code and data (after all, what is the value returned
by PROMOTE if not data?) as that "processed" is never defined and so
gets confused with "evaluated". Perhaps something that explains
or replaces "processed by EVAL" should be put in the proposal.
> I think that some extra (conceptual) machinery is necessary. For example,
> lets suppose that the language was changed as follows:
>
> EVAL only works on code, not data,
> there exists a function called PROMOTE that converts data into code.
We may want to present an evaluation model in which we have an explicit
step called "processing" or whatever. I'm not sure it makes sense to
make it a separate function (is EVAL going to signal an error on
unPRMOTEd arguments?), and I think it's ok to have the result be
a Lisp object or the usual sort (lists, etc.) rather than a new type
called "code".
> If PROMOTE were permitted to copy its argument, then part of the confusion
> in the example in the statement of the proposal LOAD-TIME-EVAL (recall "(eq
> #1=stuff #1#)") would also be eliminated because it no longer makes sense
> to talk about shared structure in CODE.
Why not? Perhaps code is the sort of object that can have shared
structure. I think that at least makes sense, even if we decide it
shouldn't be true.
∂10-Jan-89 1125 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 10 Jan 89 11:25:05 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA08433; Tue, 10 Jan 89 11:26:51 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA28898; Tue, 10 Jan 89 11:23:30 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA00186; Tue, 10 Jan 89 11:24:35 PST
Date: Tue, 10 Jan 89 11:24:35 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901101924.AA00186@clam.sun.com>
To: cperdue@Sun.COM, sandra%defun@cs.utah.edu
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Cc: cl-compiler@sail.stanford.edu
> I really dislike the idea of allowing it to be meaningful to tweak
> this variable on the fly during compilation. [Followed by
> explanation]
Well, ouch, is all I can say. I dunno. Your point looks reasonable.
-Cris
∂10-Jan-89 1145 CL-Compiler-mailer issue MACRO-ENVIRONMENT-EXTENT, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Jan 89 11:45:21 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA11487; Tue, 10 Jan 89 12:44:10 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA11604; Tue, 10 Jan 89 12:44:07 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901101944.AA11604@defun.utah.edu>
Date: Tue, 10 Jan 89 12:44:04 MST
Subject: issue MACRO-ENVIRONMENT-EXTENT, version 1
To: cl-compiler@sail.stanford.edu
Here's a new issue that discusses something that came up in relation
to issue COMPILER-LET-CONFUSION, namely the extent of &environment
objects.
Forum: Compiler
Issue: MACRO-ENVIRONMENT-EXTENT
References: CLtL p. 145-146
Issue COMPILER-LET-CONFUSION
Category: CLARIFICATION,CHANGE
Edit History: V1, 10 Jan 1988, Sandra Loosemore
Status: **DRAFT**
Problem Description:
What is the extent of environment objects received as the &ENVIRONMENT
argument of a macro function?
CLtL says that &ENVIRONMENT is "useful primarily in the rare cases
where a macro definition must explicitly expand any macros in a
subform of the macro call before computing its own expansion". While
this suggests that macro environment objects are typically used within
the dynamic scope of the macro function, the use of the word
"primarily" (rather than "only" or "exclusively" or some similarly
strong language) suggests that there may be other legitimate uses for
environment objects. But, because CLtL is silent about what those
uses might be, many users and implementors are under the impression
that environment objects have only dynamic extent.
There are some situations where using environment objects as if they
had indefinite extent provides a very useful viewpoint from which to
solve a problem. Consider the following example:
(defmacro typed-var (var) var)
(defmacro local-type-declare (declarations &body forms &environment env)
`(macrolet ((typed-var (&whole w var)
(let ((type (assoc var ',declarations)))
(if type
`(the ,(cadr type) ,var)
(macroexpand w ',env)))))
,@forms))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
Here, local macro TYPED-VAR is defined to look first in the innermost
lexical environment for information about the variable, and if there
isn't any then it recurses on the next outermost lexical environment.
The global definition of TYPED-VAR provides a terminal case to stop
the recursion.
Proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE:
State that macro environment objects received with the &ENVIRONMENT
argument of a macro function have indefinite extent.
Note that implementations are not permitted to destructively modify
environment objects once they have been passed to a macro function.
Rationale:
This legitimizes the use of macro environments as shown in the
example above.
Since data objects in Lisp otherwise have indefinite extent, it is
more consistent to give environment objects indefinite extent as
well.
Proposal MACRO-ENVIRONMENT-EXTENT:DYNAMIC:
State that macro environment objects received with the &ENVIRONMENT
argument of a macro function have only dynamic extent; it is an error
to refer to them outside the dynamic extent of that macro function.
Rationale:
This allows implementations to use somewhat more efficient techniques
for representing environment objects. For example, the storage could
be stack-allocated, or environments could be bashed destructively
instead of always being freshly heap-allocated.
Current Practice:
Macro environments appear to have indefinite extent in Lucid Common
Lisp.
A-Lisp also supports indefinite extent for macro environments and
internally uses this feature extensively. For example, the FLET,
LABELS, and FUNCTION special forms are implemented as macros using
this feature.
Cost to implementors:
For proposal INDEFINITE, some implementations may need to change. A
simple implementation of macro environments that would fit the
requirements of this proposal is to represent them as lists, pushing
information for inner contours onto the front of the list as the
contour is entered and popping the list when the contour is exited.
For proposal DYNAMIC, there is no associated implementation cost.
Cost to users:
For proposal INDEFINITE, there is no associated cost to users.
For proposal DYNAMIC, users would not be able to portably use a
simple and elegant approach to solving certain kinds of problems.
Benefits:
It is made clear whether treating environment objects as if they had
indefinite extent is portable usage.
Discussion:
Loosemore supports proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE.
-------
∂10-Jan-89 1151 CL-Compiler-mailer issue MACRO-ENVIRONMENT-CREATOR, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Jan 89 11:50:01 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA11665; Tue, 10 Jan 89 12:48:51 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA11618; Tue, 10 Jan 89 12:48:48 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901101948.AA11618@defun.utah.edu>
Date: Tue, 10 Jan 89 12:48:47 MST
Subject: issue MACRO-ENVIRONMENT-CREATOR, version 1
To: cl-compiler@sail.stanford.edu
Here's another issue relating to macro environments. I know that
issue SYNTACTIC-ENVIRONMENT-ACCESS also proposes a solution for the
same problem (among the many other things it includes), but since we
don't seem to be making much progress on this issue I thought we might
make more progress with a simpler proposal dealing with this one very
critical aspect in isolation. Adoption of this proposal would not rule
out also adopting SYNTACTIC-ENVIRONMENT-ACCESS.
Forum: Compiler
Issue: MACRO-ENVIRONMENT-CREATOR
References: CLtL p. 145-146
Issue MACRO-ENVIRONMENT-EXTENT
Issue SYNTACTIC-ENVIRONMENT-ACCESS
Category: ENHANCEMENT
Edit History: V1, 10 Jan 1989, Sandra Loosemore
Status: **DRAFT**
Problem Description:
There is no way for a user to write a portable code walker which will
correctly expand macros that use the &ENVIRONMENT argument, because
there is no way to construct a non-null environment object in the
format expected by MACROEXPAND. While the code walker could
potentially use its own environment format and its own macro expansion
function, there is still a problem because user macros are allowed to
call MACROEXPAND themselves in computing their expansions.
The problem is not as critical with other kinds of information which
is typically stored in lexical environments (such as local function
definitions and type declarations), because there are no other "hooks"
by which user programs can access this information about the
surrounding environment.
Proposal MACRO-ENVIRONMENT-CREATOR:ADD:
Add a new function:
MAKE-MACRO-ENVIRONMENT definitions &optional environment [Function]
This function creates a new macro environment object which
incorporates the macro definitions specified by the argument
DEFINITIONS. The value of this argument should be a list in
the same form as the first argument to the MACROLET special form.
If the ENVIRONMENT argument is provided, it should be a macro
environment object representing the outer lexical environment
in which the local macro definitions are made, or a value of NIL
to indicate a null environment. The default is NIL. Note that
this object is not modified by this function.
The environment object returned by this function is suitable for
passing as the environment argument to MACROEXPAND or MACROEXPAND-1.
Like environment objects received by the &ENVIRONMENT argument to
a macro, it need not be a complete lexical environment, as long as
it contains the information about local macro definitions.
Example:
(defun walk-form (form env)
(cond ...
((and (consp form) (eq (car form) 'macrolet))
(walk-macrolet form env))
...))
(defun walk-macrolet (macrolet-form outer-env)
(let ((inner-env (make-macro-environment (cadr macrolet-form) outer-env)))
(dolist (body-form (cddr macrolet-form))
(walk-form body-form inner-env))))
Rationale:
This makes it possible to write a portable code walker.
Passing the definitions of local macros in the same form as they appear
in a MACROLET special form makes MAKE-MACRO-ENVIRONMENT very easy to
use. For example, it obviates the need for users to write their own
code for destructuring macro argument lists.
Current Practice:
Lucid Common Lisp appears to have a similar internal function called
ADD-MACRO-BINDINGS-TO-ENV.
While most other implementations probably include similar
functionality internally, probably no implementation has a function
which exactly matches that described here.
Cost to implementors:
Probably fairly minor.
Cost to users:
Since this is an extension, no user code should be broken if it is
adopted.
Benefits:
This proposal fills a gaping hole in the language.
Discussion:
Issue SYNTACTIC-ENVIRONMENT-ACCESS provides a much fancier set of
functions for manipulating environment objects, including information
about lexical variables, functions, declarations, etc.. However, some
people feel that proposal is unnecessarily complicated. Issue
MACRO-ENVIRONMENT-CREATOR is an attempt to separate out the most
crucial problem in the hope that we will have an easier time agreeing
on a solution. Adoption of this issue would not prevent the adoption
of the more elaborate functionality proposed in issue
SYNTACTIC-ENVIRONMENT-ACCESS.
Loosemore supports MACRO-ENVIRONMENT-CREATOR:ADD.
-------
∂10-Jan-89 1311 CL-Compiler-mailer issue MACRO-ENVIRONMENT-CREATOR, version 1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Jan 89 13:11:13 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 518719; Tue 10-Jan-89 16:09:03 EST
Date: Tue, 10 Jan 89 16:08 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue MACRO-ENVIRONMENT-CREATOR, version 1
To: sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu, Gregor.PA@Xerox.COM
In-Reply-To: <8901101948.AA11618@defun.utah.edu>
Message-ID: <890110160847.0.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Tue, 10 Jan 89 12:48:47 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
...
Forum: Compiler
Issue: MACRO-ENVIRONMENT-CREATOR
...
Problem Description:
...
There is no way for a user to write a portable code walker which will
correctly expand macros that use the &ENVIRONMENT argument, because
there is no way to construct a non-null environment object in the
format expected by MACROEXPAND.
...
Actually, I'm not totally sure I agree with this claim. It might be beyond
the limits of most programmers, but my impression is that this is (like
your argument about COMPILER-LET :-) something someone could cook up a special
solution to if the -really- needed to.
That isn't to say that I don't think the proposal is not justified from
a practical point of view, since what you suggest is easier to think up,
easier to prove correct, etc. than the alternatives I'm alluding to.
Just for fun, I've attached some code from a part of Cloe which does
code-walking (to support a macro-version of SYMBOL-MACROLET that we've been
using during a transition to a SYMBOL-MACROLET special form). I don't have
time to explain what it does, but if anyone's bored with nothing to do they
might have the time to puzzle it out...
(DEFVAR *MAP-MACROEXPAND-1* #'MACROEXPAND-1)
(DEFUN MAP-MACROEXPAND (FORM)
(DO ((FORM FORM)
(FLAG NIL T))
(NIL)
(IF (AND (NOT (ATOM FORM))
(SYMBOLP (CAR FORM))
(MAP-FORMS-HANDLER (CAR FORM)))
(RETURN (VALUES FORM FLAG)))
(MULTIPLE-VALUE-BIND (EXPANSION DIFFERENT-P)
(FUNCALL *MAP-MACROEXPAND-1* FORM)
(IF (NOT DIFFERENT-P)
(RETURN (VALUES EXPANSION FLAG)))
(SETQ FORM EXPANSION))))
...
(DEFINE-MAP-FORMS-HANDLER LISP:MACROLET (FUNCTION FORM)
(LET ((BINDINGS (CADR FORM))
(BODY (CDDR FORM))
(FN1 (GENSYM)))
`(MACROLET ,BINDINGS
,(EVAL `(MACROLET ,BINDINGS
(MACROLET ((,FN1 (&ENVIRONMENT ENV)
(LET ((*MAP-MACROEXPAND-1* #'(LAMBDA (X) (MACROEXPAND-1 X ENV))))
`',(MAP-FORMS-PROGN ',FUNCTION ',BODY))))
(,FN1)))))))
If the technique used is not portable, I'd be curious about why. It
certainly ported fine between Genera and the Cloe Runtime (which have
extremely different pedigrees) with no special adaptation.
∂10-Jan-89 1347 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-CREATOR, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Jan 89 13:47:19 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA17036; Tue, 10 Jan 89 14:45:43 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA11766; Tue, 10 Jan 89 14:45:19 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901102145.AA11766@defun.utah.edu>
Date: Tue, 10 Jan 89 14:45:15 MST
Subject: Re: issue MACRO-ENVIRONMENT-CREATOR, version 1
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu,
Gregor.PA@Xerox.COM
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 10 Jan 89 16:08 EST
Hmmm, that's certainly a clever trick! As I understand it, you're
creating a piece of code to walk the MACROLET which establishes the
same macro definitions, and then evaluating that explicitly, right?
I'm not 100% convinced that it really works in the case where there
are explicit calls to MACROEXPAND, but I'll take your word for it and
reword the proposal so it suggests difficulty rather than
impossibility.
-Sandra
-------
∂10-Jan-89 1406 CL-Compiler-mailer **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 10 Jan 89 14:06:32 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Tue, 10 Jan 89 16:58:10 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Tue, 10 Jan 89 17:03:11 EST
Date: Tue, 10 Jan 89 17:04 EST
From: Barry Margolin <barmar@Think.COM>
Subject: **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
To: cl-compiler@sail.stanford.edu
In-Reply-To: <8901101733.AA11507@defun.utah.edu>
Message-Id: <19890110220402.8.BARMAR@OCCAM.THINK.COM>
One possible use of the COMPILED-FUNCTION type is in declarations. Are
there any implementations which have a distinguished representation for
COMPILED-FUNCTIONs, that use type declarations to compile calls to these
functions more efficiently?
While there may not be such currently, it seems like a very useful
optimization to encourage. MacLisp had a SUBRCALL function, which was
just like FUNCALL but required its first argument to be a compiled
function, and it seems like any Lisp for conventional processors could
make use of such an optimization. Many implementations already provide
"block compilation", and (FUNCALL (THE COMPILED-FUNCTION x) ...) could
potentially be as fast as a call to a named function in the caller's
compilation unit (maybe slightly slower because a COMPILED-FUNCTION
might be lexical, so the lexical environment would probably have to be
passed as an implicit argument).
Embedded language systems could probably make good use of such a
declaration, too. For example, a PROLOG implementation that turns
predicates into Lisp functions and always compiles them could use the
above.
Here's another portable application I thought of, but it's not quite as
clear-cut. A program might want to FMAKUNBOUND a bunch of macros that
it knows are only used in a limited number of functions. It could check
whether all those latter functions are compiled, and if so it knows it
is safe.
barmar
∂10-Jan-89 1451 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-CREATOR, version 1
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 10 Jan 89 14:50:58 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA12894; Tue, 10 Jan 89 14:52:06 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA08359; Tue, 10 Jan 89 14:47:55 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA00570; Tue, 10 Jan 89 14:48:55 PST
Date: Tue, 10 Jan 89 14:48:55 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901102248.AA00570@clam.sun.com>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM, sandra%defun@cs.utah.edu
Subject: Re: issue MACRO-ENVIRONMENT-CREATOR, version 1
Cc: Gregor.PA@Xerox.COM, cl-compiler@sail.stanford.edu
> Hmmm, that's certainly a clever trick! As I understand it, you're
> creating a piece of code to walk the MACROLET which establishes the
> same macro definitions, and then evaluating that explicitly, right?
> <etc.>
That sounds like what the program analyzer in Sun's
SPE product does to establish macro expansion environments
in a portable way. It has worked fine for us so far, though
the best performance is in the (common) case where the macro
expansion environment is null. I have some concern it might
prove rather slow in code with a lot of MACROLETs or
SYMBOL-MACROLETs.
I've described the technique before on some of these
mailing lists, but I don't think it sank in.
∂10-Jan-89 1505 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 10 Jan 89 15:05:18 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 10 JAN 89 15:03:51 PST
Date: 10 Jan 89 15:03 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue SHARP-COMMA-CONFUSION
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Tue, 10 Jan 89 08:53:51 MST
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
cc: Jon L White <jonl@lucid.com>, cl-compiler@sail.stanford.edu
Message-ID: <890110-150351-6806@Xerox>
Is the ` before `(#,(pop markers) #,(pop markers)) a mistake?
I.e., wouldn't ' do?
In any case, I think this points out that there are some addtional
constraints about where #, can occur, for example, it doesn't work inside
any code that is eval-when compile.
∂10-Jan-89 1519 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 10 Jan 89 15:17:41 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08892; 10 Jan 89 23:12 GMT
Date: Tue, 10 Jan 89 23:14:10 GMT
Message-Id: <15890.8901102314@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue LOAD-TIME-EVAL
To: sandra <@cs.utah.edu:sandra@defun>
In-Reply-To: Sandra J Loosemore's message of Mon, 9 Jan 89 19:22:31 MST
Cc: cl-compiler@sail.stanford.edu
> > Date: Tue, 10 Jan 89 00:20:32 GMT
> > From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
> >
> > > In interpreted code, (LOAD-TIME-VALUE <form>) is equivalent to (VALUES
> > > (EVAL (QUOTE <form>))).
> >
> > Surely not, [... mistaken comment ...]
>
> Perhaps I can rephrase this. I seem to remember having tried once
> before but apparently things got even more messed up in the process.
> The idea is that evaluation takes place in a null lexical environment,
> that it's performed by EVAL, and that exactly one value is returned.
I was confused. Quoting forms is ok (even, I now thing, self-evaluating
ones).
> > > Note that, in interpreted code, [...] Since successive evaluations
> > > of the same LOAD-TIME-VALUE expression may or may not result in an
> > > evaluation which returns a "fresh" object, destructive side-effects
> > > to the resulting object may or may not persist from one evaluation
> > > to the next.
> >
> > This sort of defeates the purpose of :READ-ONLY-P NIL.
>
> I'm not sure exactly what problem you have here. :READ-ONLY-P NIL
> says that it's OK to bash the object destructively, which is sometimes
> useful even if such destructive side-effects are not persistent.
That's probably why I said "sort of". It makes it noticeably less
useful and (more important) different from what happens in compiled
code. But you're right that it's still useful.
> > I don't understand what this explicit initialization is or why it helps.
>
> OK, here's an example.
Ah, I see. It helps because the programmer might have thought there
would be a new object each time. It doesn't help when the same object
is what's wanted, which is the case I was thinking of.
I guess what bothers me still is that the benefits of compilation
turn out to be somewhat strange. The programmer wants to write code
that will work if there's a new object each time but can still benefit
if there isn't.
> A previous paragraph says that it's OK to evaluate LOAD-TIME-VALUE forms
> only once. This is to clarify what "only once" means -- once per
> reference.
OK.
> > You might cite reasons, even if only by a phrase or two. (I'm never
> > happy when all I'm told is that "some people think it's essential".)
>
> That particular phrase is Kent's. I've long ago given up on trying to
> read Kent's mind :-), so he'll have to provide his own explanation.
I think there's some mail, but I'm having trouble finding the one
I want.
-- Jeff
∂10-Jan-89 1543 CL-Compiler-mailer Re: issue LOAD-TIME-EVAL
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Jan 89 15:43:06 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 518863; 10 Jan 89 18:40:48 EST
Date: Tue, 10 Jan 89 18:40 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue LOAD-TIME-EVAL
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
cc: sandra%defun@cs.utah.edu, cl-compiler@SAIL.Stanford.EDU
In-Reply-To: <15890.8901102314@subnode.aiai.ed.ac.uk>
Message-ID: <890110184025.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
I think it's essential to have LOAD-TIME-VALUE, including
the non-read-only data feature, because the underlying machine
is capable of providing me efficiency which I claim I need
for certain very important applications, and because all of the
alternatives which have been discussed force me to pay a
gratuitous space and/or time penalty that this facility does
not force me to pay.
∂10-Jan-89 1750 CL-Compiler-mailer Re: Issue CONSTANT-MODIFICATION, version 2
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 10 Jan 89 17:49:46 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa00715; 11 Jan 89 1:44 GMT
Date: Wed, 11 Jan 89 00:36:40 GMT
Message-Id: <16069.8901110036@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue CONSTANT-MODIFICATION, version 2
To: sandra <@cs.utah.edu:sandra@defun>
In-Reply-To: Sandra J Loosemore's message of Mon, 9 Jan 89 19:27:56 MST
Cc: cl-compiler@sail.stanford.edu
> Re why constants in compiled code can't be modified:
>
> Since "collapsing" of equivalent constants is allowed, destructively
> modifying compiled constants can cause unintended side-effects to
> other constants which just happen to look the same.
Just to clarify my rather unclear message of yesterday, what I meant
was not that there were not good reasons for forbiding modifications
but that the reasons given in the proposal stopped short of stating
those good reasons in the rationale. But I was wrong because enough
of them are stated in the Problem Description.
Sorry. I wasn't thinking very clearly last night/this morning.
∂10-Jan-89 1904 Common-Lisp-Object-System-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 10 Jan 89 19:03:59 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA17216; Tue, 10 Jan 89 19:04:42 PST
Received: from lukasiewicz.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA16547; Tue, 10 Jan 89 19:01:19 PST
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA10509; Tue, 10 Jan 89 19:03:49 PST
Date: Tue, 10 Jan 89 19:03:49 PST
From: jrose@Sun.COM (John Rose)
Message-Id: <8901110303.AA10509@lukasiewicz.sun.com>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: Gray@DSG.csc.ti.com, jonl@lucid.com,
Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Sat, 7 Jan 89 01:04 EST <19890107060409.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Date: Sat, 7 Jan 89 01:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Thu, 5 Jan 89 19:06:02 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> Probably it would be a better idea for MAKE-LOAD-FORM to return two
> values, where the first value is a form that will create the object and
> the second value is a form that will further initialize the object?
> This way the order of evaluation requirement is more explicit. It's
> upward compatible since the second value can be NIL if you don't need
> it.
Yes, that sounds good except for the problem of how to pass the object to
the second form.
...
What I had in mind was ((LAMBDA (object) ...code...)). But I like your
suggestion of evaluating the form in an environment where * is bound to the
object better. Other people should check me on this, it might just be that
you appealed to my sense of hackish kludgery.
There's a less kludgey way to get this taken care of:
Simply allow the second form to contain a reference to the object
being dumped.
Neat, yes? File-level EQ preservation works to restore the embedded
object reference "for free".
And, while we're at it, give the programmer a break, and let the second
form be optional.
Here's a more complete description of these ideas:
Define a generic function MAKE-LOAD-FORM which takes one argument and
returns one or two values. This function is called whenever
COMPILE-FILE needs to dump an object whose class is of type
STANDARD-CLASS or STRUCTURE-CLASS. (Call these types "user defined".)
It returns one or two Lisp forms, which when passed at load time to EVAL
will construct an object which is, in some class-specific sense,
"equivalent" to the original object.
Call the first form returned by MAKE-LOAD-FORM the "allocator", and the
second form the "initializer".
The allocator must wholly or partially build the reconstructed object,
and return an ordinary Lisp reference to it. The initializer, if
supplied and non-null, must finish any initialization required by the
object's class. It is an error if the result of this second form is not
EQ to the result of the first.
Both the allocator and initializer are dumped to and restored from the
binary file by COMPILE-FILE, by the usual means. It is expected that
they will consist of list structure, possibly with object of user-defined
type at the fringe.
The allocator must be dumpable without reference to the original object.
That is, in the process of dumping the original object, the dumper must
not be called upon to output the original object again until the allocator
has been completely dumped.
The initializer may contain references to arbitrary objects. In
particular, it will typically contain a reference to the original
object. Because all references to a given object in a compiled file
remain EQ across load, this can be reliably ensured simply by having
MAKE-LOAD-FORM return a reference to the original object embedded in
its second argument.
While the initializer form is being read in, the reconstructed object is
possibly in an uninitialized state, analogous to the state of an object
between the time its reference has been created by ALLOCATE-INSTANCE
and it has been processed fully by INITIALIZE-INSTANCE. Implementors
must take care in manipulating objects referenced by allocator and
initializer forms, as they would in manipulating partially initialized
objects inside INITIALIZE-INSTANCE.
(Think of the allocator as creating a reference to a chunk of storage,
which stands in for the object until such time as the initializer can
really create it. Meanwhile, the reference can be stored in other data
structure, and such stored references will become fully valid when the
object is finally initialized.)
Note that it is possible for uninitialized objects to appear in either
of the allocator or initializer forms, but when the loading process
completes, all initalizers will have been run.
A programmer of a certain class may elect to return a null initializer,
and perform all initialization in the allocator (which could then be a
simple call to MAKE-INSTANCE). In this case, some circular data
structures involving that class will not be dumpable. However, such
"simply dumped" classes may take part in circularities, as long as any
such a circularity includes at least one object which returns two values
for MAKE-LOAD-FORM, and whose allocator form breaks the circularity by
omitting all references to the next object in the circle. Therefore,
not all classes need support the two-phase dumping protocol.
(Roughly speaking, in order to win, you need to have "enough" classes
with "small" allocator forms.)
Example:
(defclass tree-with-parent () (parent children))
(defmethod make-load-form ((x tree-with-parent))
(values
`(allocate-instance (class-of x) :children ',(slot-value x 'children))
`(initialize-instance ',x :parent ',(slot-value x 'parent))))
∂10-Jan-89 2058 Common-Lisp-Object-System-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Jan 89 20:58:02 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 519020; 10 Jan 89 23:55:07 EST
Date: Tue, 10 Jan 89 23:54 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
To: John Rose <jrose@Sun.COM>
cc: Gray@DSG.csc.ti.com, jonl@lucid.com, Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <8901110303.AA10509@lukasiewicz.sun.com>
Message-ID: <19890111045446.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 10 Jan 89 19:03:49 PST
From: jrose@Sun.COM (John Rose)
Simply allow the second form to contain a reference to the object
being dumped.
Neat, yes? File-level EQ preservation works to restore the embedded
object reference "for free".
Right. You are so smart!
And, while we're at it, give the programmer a break, and let the second
form be optional.
That was always the intention. Complex capabilities shouldn't make doing
simple things harder.
Here's a more complete description of these ideas:
I pretty much agree with your description. I still hope to find time
to write a second version of the proposal, which will incorporate what
you said, except that I will try to write it in less implementation
oriented terms and more language oriented terms.
Define a generic function MAKE-LOAD-FORM which takes one argument and
returns one or two values. This function is called whenever
COMPILE-FILE needs to dump an object whose class is of type
STANDARD-CLASS or STRUCTURE-CLASS. (Call these types "user defined".)
It returns one or two Lisp forms, which when passed at load time to EVAL
will construct an object which is, in some class-specific sense,
"equivalent" to the original object.
Call the first form returned by MAKE-LOAD-FORM the "allocator", and the
second form the "initializer".
The allocator must wholly or partially build the reconstructed object,
and return an ordinary Lisp reference to it. The initializer, if
supplied and non-null, must finish any initialization required by the
object's class. It is an error if the result of this second form is not
EQ to the result of the first.
If you remove this seemingly useless error check, you don't have to special
case NIL as a second value. (EVAL NIL) never hurts.
Both the allocator and initializer are dumped to and restored from the
binary file by COMPILE-FILE, by the usual means. It is expected that
they will consist of list structure, possibly with object of user-defined
type at the fringe.
The allocator must be dumpable without reference to the original object.
That is, in the process of dumping the original object, the dumper must
not be called upon to output the original object again until the allocator
has been completely dumped.
The initializer may contain references to arbitrary objects. In
particular, it will typically contain a reference to the original
object. Because all references to a given object in a compiled file
remain EQ across load, this can be reliably ensured simply by having
MAKE-LOAD-FORM return a reference to the original object embedded in
its second argument.
While the initializer form is being read in, the reconstructed object is
possibly in an uninitialized state, analogous to the state of an object
between the time its reference has been created by ALLOCATE-INSTANCE
and it has been processed fully by INITIALIZE-INSTANCE. Implementors
must take care in manipulating objects referenced by allocator and
initializer forms, as they would in manipulating partially initialized
objects inside INITIALIZE-INSTANCE.
(Think of the allocator as creating a reference to a chunk of storage,
which stands in for the object until such time as the initializer can
really create it. Meanwhile, the reference can be stored in other data
structure, and such stored references will become fully valid when the
object is finally initialized.)
Note that it is possible for uninitialized objects to appear in either
of the allocator or initializer forms, but when the loading process
completes, all initalizers will have been run.
A programmer of a certain class may elect to return a null initializer,
and perform all initialization in the allocator (which could then be a
simple call to MAKE-INSTANCE). In this case, some circular data
structures involving that class will not be dumpable. However, such
"simply dumped" classes may take part in circularities, as long as any
such a circularity includes at least one object which returns two values
for MAKE-LOAD-FORM, and whose allocator form breaks the circularity by
omitting all references to the next object in the circle. Therefore,
not all classes need support the two-phase dumping protocol.
(Roughly speaking, in order to win, you need to have "enough" classes
with "small" allocator forms.)
Example:
(defclass tree-with-parent () (parent children))
(defmethod make-load-form ((x tree-with-parent))
(values
`(allocate-instance (class-of x) :children ',(slot-value x 'children))
`(initialize-instance ',x :parent ',(slot-value x 'parent))))
The example needs some debugging.
∂10-Jan-89 2240 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 10 Jan 89 22:40:31 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA03136g; Tue, 10 Jan 89 22:34:52 PST
Received: by bhopal id AA03302g; Tue, 10 Jan 89 22:37:09 PST
Date: Tue, 10 Jan 89 22:37:09 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901110637.AA03302@bhopal>
To: sandra%defun@cs.utah.edu
Cc: SEB1525@draper.com, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Sandra J Loosemore's message of Tue, 10 Jan 89 08:49:24 MST <8901101549.AA11362@defun.utah.edu>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
re: If you'll please look at issue DEFINING-MACROS-NON-TOP-LEVEL, it is
not a requirement that defining macros expand into EVAL-WHENs.
Yes, I'm very well aware of that (and I don't prefer it!), which is
why I reminded you that I prefer the version of defining macros that
expands into simpler constructs including EVAL-WHENs.
Well, in the rebuttals and counter rebuttals, we've lost track of
what was at issue -- namely whether or not you could implement
defining macros by expanding them into EVAL-WHEN's. I claim you
can, even when EVAL-WHEN is defined as a macro that macrolet's
EVAL-WHEN so that inner (lexical) nested instances don't cause
the evalueate twice (or, evaluate 2↑<n-1> times) problem. Your
rebuttal:
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Date: Sun, 8 Jan 89 11:17:03 MST
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL, v2
This implies that you couldn't implement DEFMACRO by expanding
it into an EVAL-WHEN, because the required magic actions would
be suppressed.
is apparently predicated on the assumption that the envelopping
macrolet takes the defining form from a toplevel status to a
non-toplevel status? If so, then I have two questions:
-- couldn't we permit MACROLET to "pass back" toplevel, just
as John Rose suggested
-- why does it matter anyway? It could conceivably matter if
the defining form expanded into something whose outter-most
wrapper was an EVAL-WHEN -- but you would do this only if you
wanted evaluation in the compile-time environment rather than
"special magic"; and my counter-rebuttal showed that you do
indeed get evaluation at that point, regardless of whether
it is considered to be at toplevel.
On the other hand, I would like to continue to raise my objection to
"special magic" that isn't regular evaluation. This tactic at best
leads to very confusing semantics, and can hardly be portable. For
example, suppose one implementation really does evaluate the
IN-PACKAGE's and DEFMACRO's it finds at toplevel, while another
doesn't really evaluate them, but merely affects some internal
compiler state. Then various macroexpander functions will not
see a consistent state between one implementation and another.
I think this leads to a satisfactory example of something that will
"break" if you retain the notion of "toplevel magic". Bacher could
come up with a related example of something that would "break" if you
take away toplevelness from the bodies of eval-whens -- it wouldn't be
a portable breakage since it would rely on an implementation-specific
"magic" processor. Of course, there would be no problem if we insisted
that EVAL-WHEN "pass back" toplevelness. [I can give an example of the
non-portable "breakage" in Lucid Common Lisp, based on some particular
"magic" that occurs with toplevel DEFUN's that doesn't occur with
inner DEFUN's -- needless to say, I consider this a bug, albeit very
minor, in Lucid Common Lisp.]
Trying to insulate the compiler's environment is a weak straw man
here. Simply shielding toplevel DEFMACROS and DEFSTRUCTS isn't
satisfactory in general, because it is wrong to think that only
two environments are at stake (the "compilation host" one and that
of the compilation target). The most realistic example I can think
of right now is one that we called "the XYZ machine problem" in our
1986 Lisp Conference paper on Lucid's retargetable compiler.
Consider compiling a program which is part of a retargetable compiler;
this program has code that is sensitive to DEFMACRO and DEFCONSTANT
definitions that will vary between one intended target and another.
During any one given compilation, this retargetable program will
itself be concerned with two environments: that on which it is expected
to be running, and that for which it is intended to be producing code.
More specifically, let's say that we are building a cross- compiler
which is intended to be _running_ on a 80386 machine, where it will
be _producing_ code to be run on a PRIME machine. Of course, we are
compililng the cross-compiler from a Sun3 workstation. Thus at any
one given instant in time, during the compilation of the cross-compiler,
there are _three_ different environments that must be separated.
The solution was that we had to introduce parallel new definers and
new accessors to reach these relativized environments. We didn't add
every conceivable definer, but enough to make the cross-compiler itself
be compilable from anywhere (maybe, just def-compiler-macro and
def-target-constant?). That is also why the Schemer's (and the
Lisp/370er's) glory in their Lisp1 world: by having only one thing to
define -- a variable's value -- there is only one aspect of an environment
to be relativized (the variables values) rather than the spectrum of
MACRO-FUNCTION, SYMBOL-FUNCTION, SYMBOL-VALUE, Defstruct-Definitions,
CONSTANTP, etc.
As it happens, I think I was the one who, way back when, put the
"special magic" into the toplevel processor of MacLisp's compiler;
probably before any other implementation did so (this question could
not arise in "residential environments" like Interlisp). It may have
been OK for the early 1970's; it is too limiting and wrong now.
-- JonL --
∂10-Jan-89 2325 CL-Compiler-mailer **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 10 Jan 89 23:25:50 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA03163g; Tue, 10 Jan 89 23:21:44 PST
Received: by bhopal id AA03410g; Tue, 10 Jan 89 23:24:01 PST
Date: Tue, 10 Jan 89 23:24:01 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901110724.AA03410@bhopal>
To: barmar@Think.COM
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Tue, 10 Jan 89 17:04 EST <19890110220402.8.BARMAR@OCCAM.THINK.COM>
Subject: **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
re: MacLisp had a SUBRCALL function, which was
just like FUNCALL but required its first argument to be a compiled
function, and it seems like any Lisp for conventional processors could
make use of such an optimization.
And indeed Lucid Common Lisp has a just such function (and also another
one corresponding to APPLY). These have not been exported to end users
yet, but are solely used in compiler optimizers etc. I'm not exactly sure
how much optimization they provide, but there should be no real obstacle
to making:
(FUNCALL (THE COMPILED-FUNCTION x) ...)
turn into
(FUNCALL-INTERNAL x ...)
at least in low safety modes.
-- JonL --
∂10-Jan-89 2330 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 10 Jan 89 23:30:25 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA03171g; Tue, 10 Jan 89 23:26:13 PST
Received: by bhopal id AA03427g; Tue, 10 Jan 89 23:28:30 PST
Date: Tue, 10 Jan 89 23:28:30 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901110728.AA03427@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cperdue@Sun.COM, sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Tue, 10 Jan 89 11:26:23 MST <8901101826.AA11549@defun.utah.edu>
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 4
There is a point in the action of Lucid's COMPILE-FILE where it "snaps"
some relevant compilation options -- in particular whether or not to
use the Development mode (fast compilation time, but not particularly
optimized output). I think it is very reasonable for parameters
affecting the treatment of constants to be "snapped" also.
-- JonL --
∂11-Jan-89 0011 CL-Compiler-mailer **DRAFT** issue QUOTE-MAY-COPY
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 11 Jan 89 00:11:38 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA03203g; Wed, 11 Jan 89 00:07:03 PST
Received: by bhopal id AA03550g; Wed, 11 Jan 89 00:09:20 PST
Date: Wed, 11 Jan 89 00:09:20 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901110809.AA03550@bhopal>
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Cc: alarson@altura.honeywell.com, cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton's message of Tue, 10 Jan 89 18:44:32 GMT <15199.8901101844@subnode.aiai.ed.ac.uk>
Subject: **DRAFT** issue QUOTE-MAY-COPY
re: > I believe that QUOTE has to return THE argument it is given.
[That's Aarons' comment].
I say, "Suuuuuuure, you will get THE argument". Now, the only question
is, how do you know what you were given? Use EQ, use EQL? Why?
I say, use COALESCABLEP. That's good enough for identity of constants.
The only conceivable reason why the EQ/EQL version of identity could
matter is if you allow runtime updating of "constants" -- in that case,
you need a pointer to the real place that was updated rather than a
pointer to an equivalent copy. But we are outlawing constant modification,
right?
-- JonL --
∂11-Jan-89 1217 CL-Compiler-mailer **DRAFT** issue QUOTE-MAY-COPY
Received: from moon.src.honeywell.com ([129.30.1.10]) by SAIL.Stanford.EDU with TCP; 11 Jan 89 08:05:30 PST
Return-Path: <alarson@src.honeywell.com>
Received: from pavo.SRC.Honeywell.COM
by moon.src.honeywell.com (5.59/smail2.6.3/06-17-88)
id AA04056; Wed, 11 Jan 89 10:15:43 CST
Posted-Date: Wed, 11 Jan 89 10:14:09 CST
Received: by pavo.src.honeywell.com (3.2/SMI-3.2)
id AA02583; Wed, 11 Jan 89 10:14:09 CST
Date: Wed, 11 Jan 89 10:14:09 CST
From: alarson@src.honeywell.com (Aaron Larson)
Message-Id: <8901111614.AA02583@pavo.src.honeywell.com>
To: jonl@lucid.com
Cc: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK, cl-compiler@sail.stanford.edu
In-Reply-To: Jon L White's message of Wed, 11 Jan 89 00:09:20 PST <8901110809.AA03550@bhopal>
Subject: **DRAFT** issue QUOTE-MAY-COPY
re: > I believe that QUOTE has to return THE argument it is given.
[That's Aarons' comment].
I say, "Suuuuuuure, you will get THE argument". Now, the only question
is, how do you know what you were given? Use EQ, use EQL? Why?
I say, use COALESCABLEP. That's good enough for identity of constants.
The only conceivable reason why the EQ/EQL version of identity could
matter is if you allow runtime updating of "constants" -- in that case,
you need a pointer to the real place that was updated rather than a
pointer to an equivalent copy. But we are outlawing constant modification,
right?
I don't think I quite agree with JonL's statement about the "only reason",
it appears to me that it would also be important in:
(defun foo () '(x y z))
(tailp (foo) (cons 'a (foo)))
My argument was an attempt to isolate the times at which the copying could
occur, and to point out that the times are not something that discussions
about QUOTE and EVAL can easily describe. For example:
(defmacro foomac () '(a b c))
(defun bar () (foomac))
(defun baz () (foomac))
Are (bar) and (baz) required to be EQ? If not, are subsequent calls to
(bar) required to be eq? If bar and baz are required to be eq, then how
about if foomac, bar, and baz are all in different files and compiled?
When is the copying EVAL allowed to occur?
I still think that we need to talk about a transformation occurring at a
specific time and specify what it is allowed to do, for example,
macroexpand then copy. What exactly the transformation is required to
preserve is essential. Is circular structure in code allowed? Only in
constants?
(defun foo () (when nil #1=(progn #1#)))
(defun bar () '#1=(a . #1#))
Are both foo and bar legal functions? In both cases the circular structure
is never evaluated.
∂11-Jan-89 1421 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:25:54 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 519425; Wed 11-Jan-89 15:11:59 EST
Date: Wed, 11 Jan 89 15:11 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: John Rose <jrose@Sun.COM>, Gray@DSG.csc.ti.com, jonl@lucid.com, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <8901111820.AA12379@defun.utah.edu>
Message-ID: <19890111201148.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 11 Jan 89 11:20:52 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
The thing that makes preservation of EQness "hard" in KCL is that its
implementation of COMPILE-FILE PRINTs out the constants. We've pretty
much concluded that there are other reasons why PRINT is not powerful
enough for this purpose, though. It would still be possible to use
READ in the loader if you wrote a custom "printer" that makes liberal
use of #, to reconstruct objects that don't PRINT right.
I don't understand. Are #n= and #n# missing from KCL? Any printer can
use those to preserve EQness.
A separate issue might be that using PRINT completely fails to reconstruct
some objects correctly, and as you say #. could be substituted in those
cases. But that has nothing to do with EQ.
∂11-Jan-89 1421 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from cs.utah.edu ([128.110.4.21]) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:21:08 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA12231; Wed, 11 Jan 89 13:18:37 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA12513; Wed, 11 Jan 89 13:18:30 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901112018.AA12513@defun.utah.edu>
Date: Wed, 11 Jan 89 13:18:27 MST
Subject: Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>, John Rose <jrose@Sun.COM>,
Gray@DSG.csc.ti.com, jonl@lucid.com, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Wed, 11 Jan 89 15:11 EST
*PRINT-CIRCLE* is only supposed to detect circularity, not sharing,
but there's nothing to prevent an implementation from detecting
sharing as well, as long as you print out all of the constants in the
file with a single call to PRINT.
I remember asking about this on the Common Lisp mailing list a few
years ago, and was told that the reason for not requiring sharing to
be detected was for efficiency of implementation.
-Sandra
-------
∂11-Jan-89 1421 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from cs.utah.edu ([128.110.4.21]) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:17:49 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA08436; Wed, 11 Jan 89 11:21:01 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA12379; Wed, 11 Jan 89 11:20:54 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901111820.AA12379@defun.utah.edu>
Date: Wed, 11 Jan 89 11:20:52 MST
Subject: Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>, John Rose <jrose@Sun.COM>,
Gray@DSG.csc.ti.com, jonl@lucid.com, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Wed, 11 Jan 89 12:53 EST
The thing that makes preservation of EQness "hard" in KCL is that its
implementation of COMPILE-FILE PRINTs out the constants. We've pretty
much concluded that there are other reasons why PRINT is not powerful
enough for this purpose, though. It would still be possible to use
READ in the loader if you wrote a custom "printer" that makes liberal
use of #, to reconstruct objects that don't PRINT right.
-Sandra
-------
∂11-Jan-89 1421 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities
Received: from ti.com by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:17:51 PST
Received: by ti.com id AA10254; Wed, 11 Jan 89 11:50:57 CST
Received: from Kelvin by tilde id AA26398; Wed, 11 Jan 89 11:44:31 CST
Message-Id: <2809532806-3951549@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 11 Jan 89 11:46:46 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: jrose@Sun.COM (John Rose), Moon@STONY-BROOK.SCRC.Symbolics.COM,
jonl@lucid.com, CL-Compiler@SAIL.STANFORD.EDU
Subject: Re: MAKE-LOAD-FORM can handle circularities
In-Reply-To: Msg of Wed, 11 Jan 89 09:11:57 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Unfortunately, we don't know yet if file-level EQ preservation works;
> see issue CONSTANT-CIRCULAR-COMPILATION.
Well, the ability to dump objects would not be very useful without that.
I think this is an argument against proposal alternative
CONSTANT-CIRCULAR-COMPILATION:NO.
∂11-Jan-89 1427 CL-Compiler-mailer Re: issue ALLOW-LOCAL-INLINE
Received: from ti.com by SAIL.Stanford.EDU with TCP; 11 Jan 89 14:23:01 PST
Received: by ti.com id AA11467; Wed, 11 Jan 89 16:22:45 CST
Received: from Kelvin by tilde id AA03001; Wed, 11 Jan 89 16:11:14 CST
Message-Id: <2809548808-4912967@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 11 Jan 89 16:13:28 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: masinter.pa@Xerox.COM
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue ALLOW-LOCAL-INLINE
In-Reply-To: Msg of 5 Jan 89 20:57 PST from masinter.pa@Xerox.COM
> I don't see a need for distinguishing between
> * always inline
> and
> * maybe inline (let the compiler decide)
>
> since "always inline" really means "let the compiler decide" anyway. The
> control over the compilers heuristics are more portably controlled via the
> SPACE vs SPEED parameters, are they not?
The heuristic approach is what I had in mind by "maybe inline"; by "always
inline" I mean to expand it inline if it is possible to, whether or not it is a
good idea. I have been interpreting the current INLINE declaration to mean
"always inline"; maybe this is another point that needs clarification.
∂11-Jan-89 1432 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities
Received: from cs.utah.edu ([128.110.4.21]) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:25:59 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA07930; Wed, 11 Jan 89 11:06:27 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA12365; Wed, 11 Jan 89 11:06:07 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901111806.AA12365@defun.utah.edu>
Date: Wed, 11 Jan 89 11:06:05 MST
Subject: Re: MAKE-LOAD-FORM can handle circularities
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore), jrose@Sun.COM (John Rose),
Moon@STONY-BROOK.SCRC.Symbolics.COM, jonl@lucid.com,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Wed, 11 Jan 89 11:46:46 CST
> Well, the ability to dump objects would not be very useful without that.
> I think this is an argument against proposal alternative
> CONSTANT-CIRCULAR-COMPILATION:NO.
How is dumping circular objects any different than dumping circular lists
or circular DEFSTRUCTs? Would it be "not useful" to be able to dump lists
at all, if circular lists could not be dumped?
As far as I can tell, people seem to have been able to accomplish
useful work using Lisp implementations that can't compile circular
constants or that don't preserve EQness of substructures. I suspect
that the ratio of constants that are circular to those that are not is
very small. Plus, the LOAD-TIME-VALUE special form could be used to
construct constants that cannot be dumped for whatever reason.
-Sandra
-------
∂11-Jan-89 1432 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from cs.utah.edu ([128.110.4.21]) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:26:15 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA04433; Wed, 11 Jan 89 09:12:22 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA12297; Wed, 11 Jan 89 09:11:58 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901111611.AA12297@defun.utah.edu>
Date: Wed, 11 Jan 89 09:11:57 MST
Subject: Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
To: jrose@Sun.COM (John Rose)
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Gray@DSG.csc.ti.com, jonl@lucid.com,
Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: jrose@Sun.COM (John Rose), Tue, 10 Jan 89 19:03:49 PST
Just to set the record straight:
> Date: Tue, 10 Jan 89 19:03:49 PST
> From: jrose@Sun.COM (John Rose)
>
> File-level EQ preservation works to restore the embedded
> object reference "for free".
Unfortunately, we don't know yet if file-level EQ preservation works;
see issue CONSTANT-CIRCULAR-COMPILATION. KCL is one implementation
where COMPILE-FILE/LOAD does not now preserve EQness of structures.
-Sandra
-------
∂11-Jan-89 1433 CL-Compiler-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from lucid.com ([192.26.25.1]) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:33:14 PST
Received: from blacksox ([192.9.201.39]) by heavens-gate.lucid.com id AA03444g; Wed, 11 Jan 89 08:57:15 PST
Received: by blacksox id AA01229g; Wed, 11 Jan 89 08:59:40 pst
Date: Wed, 11 Jan 89 08:59:40 pst
From: Eric Benson <eb@lucid.com>
Message-Id: <8901111659.AA01229@blacksox>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: jrose@Sun.COM, Gray@DSG.csc.ti.com, jonl@lucid.com,
Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Tue, 10 Jan 89 23:54 EST <19890111045446.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
The dumper should be allowed to compile the forms returned by
MAKE-LOAD-FORM. That would be a way of trading increased dumping time
for decreased loading time. If the file is to be loaded many times
that would be a desirable trade-off. Also, it is then possible to
load it into a Lisp that has no EVAL.
∂11-Jan-89 1434 CL-Compiler-mailer **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
Received: from lucid.com ([192.26.25.1]) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:33:06 PST
Received: from blacksox ([192.9.201.39]) by heavens-gate.lucid.com id AA03440g; Wed, 11 Jan 89 08:42:42 PST
Received: by blacksox id AA01223g; Wed, 11 Jan 89 08:45:06 pst
Date: Wed, 11 Jan 89 08:45:06 pst
From: Eric Benson <eb@lucid.com>
Message-Id: <8901111645.AA01223@blacksox>
To: jonl@lucid.com
Cc: barmar@Think.COM, cl-compiler@sail.stanford.edu
In-Reply-To: Jon L White's message of Tue, 10 Jan 89 23:24:01 PST <8901110724.AA03410@bhopal>
Subject: **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
Date: Tue, 10 Jan 89 23:24:01 PST
From: Jon L White <jonl@lucid.com>
re: MacLisp had a SUBRCALL function, which was
just like FUNCALL but required its first argument to be a compiled
function, and it seems like any Lisp for conventional processors could
make use of such an optimization.
And indeed Lucid Common Lisp has a just such function (and also another
one corresponding to APPLY). These have not been exported to end users
yet, but are solely used in compiler optimizers etc. I'm not exactly sure
how much optimization they provide, but there should be no real obstacle
to making:
(FUNCALL (THE COMPILED-FUNCTION x) ...)
turn into
(FUNCALL-INTERNAL x ...)
at least in low safety modes.
Not quite. Lucid's optimization is for the type PROCEDURE, which is
used for both interpreted and compiled functions. It is equivalent to
the new strict definition of FUNCTION. An interpreted function is
essentially just a compiled closure that calls EVAL. It is only
distinguished by a bit in the header so that COMPILED-FUNCTION-P is
not true of it. The optimized version of FUNCALL eliminates a piece of
code that is equivalent to something like
(UNLESS (PROCEDUREP F)
(SETQ F (COERCE-TO-PROCEDURE F)))
∂11-Jan-89 1438 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:42:06 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06778; 11 Jan 89 18:52 GMT
Date: Wed, 11 Jan 89 18:54:12 GMT
Message-Id: <18154.8901111854@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: **DRAFT** issue QUOTE-MAY-COPY
To: Jon L White <jonl%lucid.com@NSS.Cs.Ucl.AC.UK>,
jeff <@NSS.Cs.Ucl.AC.UK:jeff@aiai.edinburgh.ac.uk>
In-Reply-To: Jon L White's message of Wed, 11 Jan 89 00:09:20 PST
Cc: alarson@altura.honeywell.com, cl-compiler@sail.stanford.edu
> The only conceivable reason why the EQ/EQL version of identity could
> matter is if you allow runtime updating of "constants" -- in that case,
> you need a pointer to the real place that was updated rather than a
> pointer to an equivalent copy. But we are outlawing constant modification,
> right?
You might want an EQ- or EQL-unique object to use as an index into
a table or hash table. But in general, the fact that EQ or EQL can
tell the difference may mean that the user wants to make that
distinction even though it can't be made in any other way.
LOAD-TIME-VALUE might help in all of these cases (whether you want
to modify or just to have a unique object), except that we might
end up deciding that LOAD-TIME-VALUE gives a new object each time
in interpreted code and that QUOTE does not. The situation would
be better in compiled code.
My remaining concern is that, as much as possible, EQL uninterned
symbols stay EQL and non-EQL ones stay non-EQL. Except for the
possibility that this will not happen, such symbols might be pretty
good as EQL-unique objects.
∂11-Jan-89 1431 Common-Lisp-Object-System-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:25:28 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 519263; Wed 11-Jan-89 12:37:35 EST
Date: Wed, 11 Jan 89 12:37 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
To: Eric Benson <eb@lucid.com>
cc: jrose@Sun.COM, Gray@DSG.csc.ti.com, jonl@lucid.com, Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <8901111659.AA01229@blacksox>
Message-ID: <19890111173731.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 11 Jan 89 08:59:40 pst
From: Eric Benson <eb@lucid.com>
The dumper should be allowed to compile the forms returned by
MAKE-LOAD-FORM. That would be a way of trading increased dumping time
for decreased loading time. If the file is to be loaded many times
that would be a desirable trade-off. Also, it is then possible to
load it into a Lisp that has no EVAL.
I agree. Didn't the version 1 writeup say that?
∂11-Jan-89 1431 Common-Lisp-Object-System-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:25:38 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 519270; Wed 11-Jan-89 12:53:09 EST
Date: Wed, 11 Jan 89 12:53 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: John Rose <jrose@Sun.COM>, Gray@DSG.csc.ti.com, jonl@lucid.com, Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <8901111611.AA12297@defun.utah.edu>
Message-ID: <19890111175308.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 11 Jan 89 09:11:57 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Just to set the record straight:
> Date: Tue, 10 Jan 89 19:03:49 PST
> From: jrose@Sun.COM (John Rose)
>
> File-level EQ preservation works to restore the embedded
> object reference "for free".
Unfortunately, we don't know yet if file-level EQ preservation works;
see issue CONSTANT-CIRCULAR-COMPILATION. KCL is one implementation
where COMPILE-FILE/LOAD does not now preserve EQness of structures.
If file-level EQ preservation is punted, MAKE-LOAD-FORM only returns one
value, and this whole discussion is punted. So it doesn't actually
matter that we don't know yet (except that we might be wasting our
time).
Personally, I think file-level EQ preservation is important and would
hate to see it excluded from the language specification.
To throw a digression into the discussion, the only thing I know of
that's hard about file-level EQ preservation is EQness of CDRs in
implementations with cdr-coding of lists. Even that's only "hard" in
the sense that it is difficult to convince implementors to do EQness
checking by treating each individual cons as a separate object, rather
than treating the whole list as a single object, because it seems (and
in fact is) less efficient. Symbolics Genera 7.x gets this wrong. What
about the TI Explorer?
∂11-Jan-89 1458 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities
Received: from ti.com by SAIL.Stanford.EDU with TCP; 11 Jan 89 13:41:26 PST
Received: by ti.com id AA11219; Wed, 11 Jan 89 15:40:34 CST
Received: from Kelvin by tilde id AA00615; Wed, 11 Jan 89 14:07:53 CST
Message-Id: <2809541414-4468719@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 11 Jan 89 14:10:14 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>, jonl@lucid.com,
CL-Compiler@SAIL.STANFORD.EDU
Subject: Re: MAKE-LOAD-FORM can handle circularities
In-Reply-To: Msg of Wed, 11 Jan 89 12:53 EST from David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
> To throw a digression into the discussion, the only thing I know of
> that's hard about file-level EQ preservation is EQness of CDRs in
> implementations with cdr-coding of lists. Even that's only "hard" in
> the sense that it is difficult to convince implementors to do EQness
> checking by treating each individual cons as a separate object, rather
> than treating the whole list as a single object, because it seems (and
> in fact is) less efficient. Symbolics Genera 7.x gets this wrong. What
> about the TI Explorer?
Good point. The Explorer also treats a list as a single object, without
looking for matches on successive cdrs. Given the efficiency
considerations involved, I would be reluctant to consider this a bug.
Issue CONSTANT-CIRCULAR-COMPILATION does need to address this, at least in
the "current practice" section.
∂11-Jan-89 1458 CL-Compiler-mailer Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Jan 89 14:47:27 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA17453; Wed, 11 Jan 89 15:44:43 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA12661; Wed, 11 Jan 89 15:44:31 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901112244.AA12661@defun.utah.edu>
Date: Wed, 11 Jan 89 15:44:29 MST
Subject: Re: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
To: Eric Benson <eb@lucid.com>
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, jrose@Sun.COM, Gray@DSG.csc.ti.com,
jonl@lucid.com, Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: Eric Benson <eb@lucid.com>, Wed, 11 Jan 89 08:59:40 pst
> The dumper should be allowed to compile the forms returned by
> MAKE-LOAD-FORM.
This sounds like a good use for the proposed new LOAD-TIME-VALUE
special form.
-Sandra
-------
∂11-Jan-89 1510 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Jan 89 15:04:18 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 519670; Wed 11-Jan-89 17:57:41 EST
Date: Wed, 11 Jan 89 17:57 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: **DRAFT** issue QUOTE-MAY-COPY
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
cc: jonl@Lucid.COM, alarson@altura.honeywell.com,
CL-Compiler@SAIL.Stanford.EDU, KMP@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <18154.8901111854@subnode.aiai.ed.ac.uk>
Message-ID: <890111175732.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Wed, 11 Jan 89 18:54:12 GMT
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
...
LOAD-TIME-VALUE might help in all of these cases (whether you want
to modify or just to have a unique object), except that we might
end up deciding that LOAD-TIME-VALUE gives a new object each time
in interpreted code and that QUOTE does not. The situation would
be better in compiled code.
...
Careful! We won't ever end up deciding that LOAD-TIME-VALUE gives a different
value every time. We may end up deciding that LOAD-TIME-VALUE evaluates
the form every time. The two may or may not be related.
Consider the difference between
(LOAD-TIME-VALUE (LIST 1 2 3))
which will give unique lists every time its evaluated, and so will give
new values if evaluated multiple times and
(LOAD-TIME-VALUE (OR (GETHASH :1-2-3 *MY-CACHE*)
(SETF (GETHASH :1-2-3 *MY-CACHE*) (LIST 1 2 3))))
which is not susceptible to re-evaluation problems [unless I change
*MY-CACHE* somewhere else, of course].
Personally I think this whole discussion is mis-guided. QUOTE is not what
copies. The process of turning `source code' into `executable gunk' may
not preserve EQ-ness, but QUOTE itself will. The effect may appear as if
QUOTE is not doing its job, but QUOTE will be busy doing the best it can.
The number of copies made should not exceed the number of transformations
made between `source code' and `executable gunk' ... Normally that will be
1, but in the case of explicit calls to EVAL it may be greater since those
force a transformation -- or maybe many transformations -- at runtime.
In many ways reminds me of discussions about "e and `functions which
don't evaluate their arguments': functions just get called with arguments.
It quickly becomes clear when APPLY becomes involved that nothing a
function does can keep its arguments from being evaluated if the caller
wants to evaluate them. It may be useful to think of functions as evaluating
their arguments or not, but it's sloppy. Similarly here, if you want to
talk about QUOTE copying or not copying, that's ok if you can keep it
straight (though it doesn't sound to me like some people can), but in my
opinion it's sloppy and prone to lead you down alleys you oughtn't bother
exploring...
I'm not so much talking to Jeff here, as I am talking to some of the others
in this discussion. It's just that Jeff's notes keep reminding me and this
is the first chance I've had to pipe in for a bit...
∂11-Jan-89 1515 CL-Compiler-mailer MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Received: from lucid.com ([192.26.25.1]) by SAIL.Stanford.EDU with TCP; 11 Jan 89 12:59:51 PST
Received: from blacksox ([192.9.201.39]) by heavens-gate.lucid.com id AA03707g; Wed, 11 Jan 89 12:55:13 PST
Received: by blacksox id AA01277g; Wed, 11 Jan 89 12:57:38 pst
Date: Wed, 11 Jan 89 12:57:38 pst
From: Eric Benson <eb@lucid.com>
Message-Id: <8901112057.AA01277@blacksox>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: jrose@Sun.COM, Gray@DSG.csc.ti.com, jonl@lucid.com,
Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Wed, 11 Jan 89 12:37 EST <19890111173731.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: MAKE-LOAD-FORM can handle circularities [was Compilation implications]
Date: Wed, 11 Jan 89 12:37 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Wed, 11 Jan 89 08:59:40 pst
From: Eric Benson <eb@lucid.com>
The dumper should be allowed to compile the forms returned by
MAKE-LOAD-FORM. That would be a way of trading increased dumping time
for decreased loading time. If the file is to be loaded many times
that would be a desirable trade-off. Also, it is then possible to
load it into a Lisp that has no EVAL.
I agree. Didn't the version 1 writeup say that?
Maybe it did. Some CL mail has gotten lost on its way here, due to
lossage at SAIL. Or I might have just overlooked it.
∂11-Jan-89 1744 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Jan 89 17:44:19 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA21802; Wed, 11 Jan 89 18:41:09 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA12769; Wed, 11 Jan 89 18:40:33 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901120140.AA12769@defun.utah.edu>
Date: Wed, 11 Jan 89 18:40:32 MST
Subject: Re: **DRAFT** issue QUOTE-MAY-COPY
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK, jonl@Lucid.COM,
alarson@altura.honeywell.com, CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Wed, 11 Jan 89 17:57 EST
I think we're all pretty much agreed that the writeup for this issue
needs an overhaul, perhaps going as far as to rename the issue and its
various proposals. I was hesistant to do so right before the meeting,
for fear that such drastic last-minute changes would leave everybody
even more hopelessly confused. (I've noticed that this has happened a
few times with cl-cleanup issues.) After next week hopefully we all
won't be in such a panic and we can give this the attention it
deserves.
-Sandra
-------
∂11-Jan-89 1805 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 11 Jan 89 18:05:07 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04351g; Wed, 11 Jan 89 18:00:46 PST
Received: by bhopal id AA07073g; Wed, 11 Jan 89 18:03:02 PST
Date: Wed, 11 Jan 89 18:03:02 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901120203.AA07073@bhopal>
To: masinter.pa@Xerox.COM
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM's message of 10 Jan 89 15:03 PST <890110-150351-6806@Xerox>
Subject: issue SHARP-COMMA-CONFUSION
re: Is the ` before `(#,(pop markers) #,(pop markers)) a mistake?
No, it's just superfluous (since there are no comma markers in the form).
re: ... constraints about where #, can occur, for example, it doesn't work
inside any code that is eval-when compile.
I think you'll find it much more difficult than that to explain, especially
in the presence of #. and "special magic" used by COMPILE-FILE. There
are no such restrictions (nor inherent ambiguities) on LOAD-TIME-VALUE.
-- JonL --
∂11-Jan-89 2040 CL-Compiler-mailer issue MACRO-ENVIRONMENT-CREATOR, version 1
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 11 Jan 89 20:40:07 PST
Received: from GANG-GANG.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via INTERNET with SMTP id 258917; 11 Jan 89 23:36:21 EST
Date: Wed, 11 Jan 89 23:35 EST
From: Glenn S. Burke <gsb@ALDERAAN.SCRC.Symbolics.COM>
Subject: issue MACRO-ENVIRONMENT-CREATOR, version 1
To: sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8901101948.AA11618@defun.utah.edu>
Message-ID: <19890112043557.0.GSB@GANG-GANG.SCRC.Symbolics.COM>
You still need the ability to handle flet (i.e., shadow macro definitions).
While one could say that a definition with only a name does that, i.e.
(make-macro-environment '((flet-function-name-1) (flet-function-name-2))),
a syntax like this is not amenable to any future extension.
∂11-Jan-89 2135 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-CREATOR, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Jan 89 21:35:27 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA25797; Wed, 11 Jan 89 22:35:12 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA12955; Wed, 11 Jan 89 22:34:56 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901120534.AA12955@defun.utah.edu>
Date: Wed, 11 Jan 89 22:34:55 MST
Subject: Re: issue MACRO-ENVIRONMENT-CREATOR, version 1
To: Glenn S. Burke <gsb@ALDERAAN.SCRC.Symbolics.COM>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Glenn S. Burke <gsb@ALDERAAN.SCRC.Symbolics.COM>, Wed, 11 Jan 89 23:35 EST
Sigh, I'd overlooked that. I guess I'll have to think about this
issue some more.
Actually it is not strictly necessary for a code walker do anything
special for local function definitions, but once again this involves a
non-obvious "trick". As I've mentioned elsewhere, A-Lisp internally
does a source-to-source transformation to turn FLET and LABELS into
LETs and MACROLETs. For example, it turns
(flet ((foo (x) ...))
...)
into something like
(let ((temp #'(lambda (x) ...)))
(macrolet ((foo (&rest args) `(funcall temp ,@args)))
....))
where "temp" is really a gensym. It takes a little extra work to make
FUNCTION work right.
-Sandra
-------
∂11-Jan-89 2158 CL-Compiler-mailer Re: **DRAFT** issue QUOTE-MAY-COPY
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 11 Jan 89 21:57:39 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa01984; 12 Jan 89 5:46 GMT
Date: Thu, 12 Jan 89 05:49:16 GMT
Message-Id: <18965.8901120549@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: **DRAFT** issue QUOTE-MAY-COPY
To: sandra <@cs.utah.edu:sandra@defun>,
Kent M Pitman <KMP@scrc-stony-brook.arpa>, alarson@altura.honeywell.com
Cc: jonl <@sail.stanford.edu:jonl@lucid.com>, CL-Compiler@sail.stanford.edu
> I think we're all pretty much agreed that the writeup for this issue
> needs an overhaul, perhaps going as far as to rename the issue and its
> various proposals. I was hesistant to do so right before the meeting,
> for fear that such drastic last-minute changes would leave everybody
> even more hopelessly confused. (I've noticed that this has happened a
> few times with cl-cleanup issues.)
Perhaps we could call it QUOTE-SEMANTICS. This may suggest that we
generalize the issue somewhat, and perhaps change the boundaries of
other issues. I haven't thought of suitable names for the proposals.
> After next week hopefully we all won't be in such a panic and we can
> give this the attention it deserves.
We may have to remember to do something to make sure we're allowed to
do this and not be cut off because this January meeting is supposedly
the final technical meeting or something of that sort.
∂11-Jan-89 2346 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Jan 89 23:46:12 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 11 JAN 89 23:44:04 PST
Date: 11 Jan 89 23:43 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue SHARP-COMMA-CONFUSION
In-reply-to: Jon L White <jonl@lucid.com>'s message of Wed, 11 Jan 89
18:03:02 PST
To: Jon L White <jonl@lucid.com>
cc: masinter.pa@Xerox.COM, sandra%defun@cs.utah.edu,
cl-compiler@sail.stanford.edu
Message-ID: <890111-234404-11837@Xerox>
While I believe that LOAD-TIME-VALUE has cleaner semantics, and that
suitably specifying the places where #, actually can "work" is difficult,
I'm uncomfortable with the position that we should toss something that's
been in Lisp for 8 years just because we can't find a way of specifying it
with only a few months thought.
Here's a version of "restricted" #, that may have as clean semantics as
LOAD-TIME-VALUE:
(a) restrict the read macro #, to only appear in places where comma can
appear.
(b) add a meta-rule to backquote processing that [#,form] is interpreted as
(LIST (LOAD-TIME-VALUE form)) (in the same way that [,form] is interpreted
as (LIST form).)
(c) add a meta-rule that
`(x1 x2 x3 ... xn . #,form) may be interpreted to mean
(append [x1] [x2] ... [xn] (LOAD-TIME-VALUE form)).
This is an incompatible change for current users of #, but the
incompatibility is minor for most uses.
It treats #, more like , than like #. and gives a consistent
interpretation of it.
∂12-Jan-89 0323 CL-Compiler-mailer **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 12 Jan 89 03:23:00 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04768g; Thu, 12 Jan 89 03:18:30 PST
Received: by bhopal id AA01077g; Thu, 12 Jan 89 03:20:41 PST
Date: Thu, 12 Jan 89 03:20:41 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901121120.AA01077@bhopal>
To: eb@bhopal
Cc: barmar@Think.COM, cl-compiler@sail.stanford.edu
In-Reply-To: Eric Benson's message of Wed, 11 Jan 89 08:45:06 pst <8901111645.AA01223@blacksox>
Subject: **DRAFT** issue COMPILED-FUNCTION-REQUIREMENTS, version 2
re: ... but there should be no real obstacle to making:
(FUNCALL (THE COMPILED-FUNCTION x) ...)
turn into
(FUNCALL-INTERNAL x ...)
at least in low safety modes.
Not quite. Lucid's optimization is for the type PROCEDURE, which is
used for both interpreted and compiled functions. ...
This ought to work, because COMPILED-FUNCTION is a subtype of
PROCEDURE. [If it doesn't, then we have YetAnotherSubtypepBug!]
True, we should also be able to optimize a form like:
(FUNCALL (THE INTERPRETED-FUNCTION x) ...)
if there were such a type, since "interpreted" functions are just
procedures that "trampoline" back in to the interpreter.
Incidentally, VAX/NIL did this trick too back in 1979; I'm not at all
sure that it was the first to do so. Anyone know of an earlier Lisp
that *always* had something instantly FUNCALLable in the function cell
-- either to an undefined trap routine, or to a trampoline back into
APPLY?
-- JonL --
∂12-Jan-89 0346 CL-Compiler-mailer **DRAFT** issue QUOTE-MAY-COPY
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 12 Jan 89 03:46:39 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04785g; Thu, 12 Jan 89 03:41:28 PST
Received: by bhopal id AA01132g; Thu, 12 Jan 89 03:43:45 PST
Date: Thu, 12 Jan 89 03:43:45 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901121143.AA01132@bhopal>
To: alarson@src.honeywell.com
Cc: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK, cl-compiler@sail.stanford.edu
In-Reply-To: Aaron Larson's message of Wed, 11 Jan 89 10:14:09 CST <8901111614.AA02583@pavo.src.honeywell.com>
Subject: **DRAFT** issue QUOTE-MAY-COPY
re: I don't think I quite agree with JonL's statement about the "only reason",
it appears to me that it would also be important in:
(defun foo () '(x y z))
(tailp (foo) (cons 'a (foo)))
Hmmm, do you remember that the TAILP proposal got bogged down when
it was noticed that a :TEST argument was necessary?
re: My argument was an attempt to isolate the times at which the copying could
occur, and to point out that the times are not something that discussions
about QUOTE and EVAL can easily describe.
Well, I'm not sure what the problem is with focusing on EVAL/COMPILE.
I sent out my note before reading your suggestion about "promotion";
that sounds like what I've been saying all along. Namely, that just
because something is READ into a lisp doesn't mean it is a constant;
it only becomes a "constant" when processed by EVAL (or a compiler)
in an evaluation context. "Promotion" wouldn't be a bad term for
that process, and might help "isolate the times", as you say.
However, we still haven't seen any good reason as to why EQ or EQL
must be the equivalence predicate for constants; why not EQUAL? or
COALESABLEP? Happily, symbols have the EQ-for-COALESABLEP property,
and characters and fixnums have the EQL-for-COALESABLEP property.
But so what if random strings, lists or defstructs don't have these
properties?
-- JonL --
∂12-Jan-89 0811 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Jan 89 08:11:34 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06457; Thu, 12 Jan 89 09:10:50 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA13332; Thu, 12 Jan 89 09:10:44 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901121610.AA13332@defun.utah.edu>
Date: Thu, 12 Jan 89 09:10:43 MST
Subject: Re: issue SHARP-COMMA-CONFUSION
To: masinter.pa@Xerox.COM
Cc: Jon L White <jonl@lucid.com>, sandra%defun@cs.utah.edu,
cl-compiler@sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM, 11 Jan 89 23:43 PST
What you propose doesn't seem totally unreasonable to me, but still:
- it would be incompatible with current uses of #, outside of backquote.
- it doesn't really buy you any functionality, since you can trivially
accomplish the same thing using (load-time-eval ,form).
One advantage of removing #, from the standard is that implementations
could retain their existing definition of #, as an extension. If we
redefine the behavior of #, instead, then the old behavior -must- go
away.
-Sandra
-------
∂12-Jan-89 0852 CL-Compiler-mailer Re: Issue CONSTANT-MODIFICATION, version 2
Received: from ti.com by SAIL.Stanford.EDU with TCP; 12 Jan 89 08:51:53 PST
Received: by ti.com id AA15223; Thu, 12 Jan 89 10:51:53 CST
Received: from Kelvin by tilde id AA21883; Thu, 12 Jan 89 10:36:29 CST
Message-Id: <2809615107-8896308@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 12 Jan 89 10:38:27 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: cl-compiler@sail.stanford.edu
Subject: Re: Issue CONSTANT-MODIFICATION, version 2
In-Reply-To: Msg of Tue, 10 Jan 89 00:39:18 GMT from Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
> But why can't constants be modified in compiled code? It seems clear
> that they could be, so there must be some reasons why they aren't
> always modifiable, and those are the real reasons.
Besides the considerations of current practice and consistency, there's another
point that should be added to the rationale: modification of constants is a
dangerous and error-prone thing to do. Since our object file loader places
constants in write-protected memory, I have received many complaints from users
who think they have found a bug because they get an error on a store, but when
I talk to them about what they are doing, in nearly every case it turns out
that the modification they were prevented from doing was not really what they
wanted to do anyway. I can recall only two cases where users understood the
consequences of modifying a constant and had a legitimate reason for doing so;
for them, the LOAD-TIME-VALUE form provides a way to get a modifiable value.
For example, a naive programmer might write something like
(defun hack (n)
(let ((string "........."))
(setf (char string n) #\X)
(write-string string)))
which works as expected only the first time it is called. This is a common
mistake for programmers with previous experience in languages such as Pascal
where a string assignment copies the string.
∂12-Jan-89 1037 CL-Compiler-mailer Re: Issue: COMPILER-LET-CONFUSION (Version 4)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 12 Jan 89 10:37:18 PST
Received: by ti.com id AA15784; Thu, 12 Jan 89 12:36:00 CST
Received: from Kelvin by tilde id AA24796; Thu, 12 Jan 89 12:29:14 CST
Message-Id: <2809621884-9303507@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 12 Jan 89 12:31:24 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@CS.UTAH.EDU, CL-Compiler@SAIL.Stanford.EDU
Subject: Re: Issue: COMPILER-LET-CONFUSION (Version 4)
In-Reply-To: Msg of Sun, 8 Jan 89 17:58 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> Statements of support (for either option) for inclusion in the
> Discussion are solicited anew from anyone with an opinion on this topic.
I favor COMPILER-LET-CONFUSION:REPAIR.
∂12-Jan-89 1143 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 12 Jan 89 11:43:19 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 12 JAN 89 11:16:13 PST
Date: 12 Jan 89 11:15 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue SHARP-COMMA-CONFUSION
In-reply-to: sandra%defun@cs.utah.edu (Sandra J Loosemore)'s message of
Thu, 12 Jan 89 09:10:43 MST
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
cc: masinter.pa@Xerox.COM, Jon L White <jonl@lucid.com>,
cl-compiler@sail.stanford.edu
Message-ID: <890112-111613-12867@Xerox>
We could make uses of #, outside of backquote "undefined", or add some more
rules for how to interpret #, in those situations.
The question is: which is better, remove backquote from the standard, or
leave it in in restricted form?
:REMOVE is incompatible with all uses of #,
:RESTRICT is incompatible with all uses outside of backquote.
So RESTRICT is "less" incompatible: it will cause fewer of the programs
that use #, to no longer be admissible.
Re: "it doesn't really buy you any functionality". Neither does "quote" or
"backquote" for that matter. Read-macro syntax is merely a more readable
shorthand. (Your example should have been ,(load-time-eval form) instead of
(load-time-eval ,form).)
I don't like the reasoning which I paraphrase "if we take this out instead
of define it, implementations can retain their existing definitions as an
extension."
The major problem with the proposal I outlined about backquote is that it
CONSes. I.e., if I say
'(a b #,foo) it should not cons a new list, but if I say
`(a b #,foo) with the definition I proposed, it would.
In fact, '(a b #,foo) should turn itself into
(load-time-constant (list 'a 'b foo)).
∂12-Jan-89 1201 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Jan 89 12:01:13 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 520341; Thu 12-Jan-89 14:58:09 EST
Date: Thu, 12 Jan 89 14:57 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue SHARP-COMMA-CONFUSION
To: masinter.pa@Xerox.COM
cc: sandra%defun@cs.utah.edu, jonl@lucid.com,
cl-compiler@sail.stanford.edu
In-Reply-To: <890112-111613-12867@Xerox>
Message-ID: <890112145758.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
While I think #, or LOAD-TIME-VALUE is an important functionality to have
in some form, I agree with those who say that the number of source code
lines which use #, are very small. As such, I don't think we should waste
a lot of effort specifying what #, should do since I believe the process
of converting any uses of #, to uses of LOAD-TIME-VALUE will be utterly
straightforward if we just provide rewrite advice.
Moreover, unless the semantics you come up with for #, are exactly those
which implementations already adhere to, then you're introducing a lurking
compatibility problem which is perhaps worse than having #, disappear.
People will be forced to check their code for the need to rewrite anyway
if it doesn't always work compatibly. While they're in there, they might as
well just rewrite to LOAD-TIME-VALUE explicitly to make sure their intent
is clear.
I argue that a change which is less compatible, but more reliably detectable
is better than a change which is more compatible but less reliably detectable.
For example: The transition from Maclisp / to CL / was one of the biggest
hurdles that Macsyma had to overcome. The fact that / would continue to do
something which was mostly right but different in subtle ways was not a help
but a hindrance. If there had been no / operator, we'd have been better off.
Ultimately, we shadowed / in Macsyma and I think that to this day it is not
used for fear that the many implementors who grew up on Maclisp / will get
confused.
I think this case of #, is similar to this example. If you just remove it,
you avoid a very big potential for confusion and permit implementations
to provide compatibility as they see it to be appropriate for the needs of
their customers.
∂12-Jan-89 1223 CL-Compiler-mailer Re: issue SHARP-COMMA-CONFUSION
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 12 Jan 89 12:23:47 PST
Received: from Semillon.ms by ArpaGateway.ms ; 12 JAN 89 12:14:40 PST
Date: 12 Jan 89 12:14 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue SHARP-COMMA-CONFUSION
In-reply-to: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>'s message
of Thu, 12 Jan 89 14:57 EST
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
cc: masinter.pa@Xerox.COM, sandra%defun@cs.utah.edu, jonl@lucid.com,
cl-compiler@sail.stanford.edu
Message-ID: <890112-121440-13057@Xerox>
I like the argument "we should take it out and users should convert their
code" better than the argument "we should take it out and implementors
should continue to provide it as an 'extension'".
I'd even like "we should take it out and implementors can offer it in a
'backward compatibility' mode". This could be done by having the CLtL
readtable different than the ANSI Common Lisp readtable, for example.
∂13-Jan-89 1340 CL-Compiler-mailer Issue: DEFINING-MACROS-NON-TOP-LEVEL (Version 7)
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by SAIL.Stanford.EDU with TCP; 13 Jan 89 13:40:42 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by Riverside.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 308360; Fri 13-Jan-89 16:38:54 EST
Date: Fri, 13 Jan 89 16:38 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: DEFINING-MACROS-NON-TOP-LEVEL (Version 7)
To: CL-Compiler@SAIL.Stanford.EDU
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <890113163801.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
I very strongly oppose this business of having all macro forms treated in
their own lexical environment. Among other things, this makes MACROLET and
DEFMACRO asymmetric.
I am ammenable to special cases for DEFUN because its effect takes place
at runtime.
I think the correct solution to this situation is to say that if any of
these defining forms occur in other than the toplevel environment, then it
is as if EVAL was used.
Briefly, that means that I think that
(DEFUN FOO (X) (DEFMACRO BAR (Y) ...) ...)
should be treated conceptually like:
(DEFUN FOO (X) (EVAL '(DEFMACRO BAR (Y) ...)) ...)
I don't really mind some implementation does the optimization of
implementing this behavior by:
(DEFUN #:FOO-INTERNAL-0 (Y) ...)
(DEFUN FOO (X) (SETF (MACRO-FUNCTION 'BAR) #'#:FOO-INTERNAL-0) ...)
in order to make sure the stuff gets compiled, as long as the advertised
behavioral equivalency to EVAL is preserved.
I think very strongly that there is no other rational interpretation.
-----
None of the above is dependent on the following, but As an addendum, I think
the right solution to the EVAL-WHEN problem is to say that in any non-toplevel
position, EVAL-WHEN simply behaves as if defined by:
(DEFMACRO EVAL-WHEN (TIMES &BODY FORMS)
(IF (MEMBER 'EVAL TIMES) `(EVAL '(PROGN ,@FORMS))
NIL))
Note well that a use of (EVAL-WHEN (EVAL LOAD) ...x...) would no longer be
equivalent to (PROGN ...x...) because the environment is different in non-top-level
positions; the former would use null lexical, while the latter would use current
lexical. Nevertheless, the change would be compatible because the only place you
could tell the difference would be in non-top-level positions, where EVAL-WHEN
is currently disallowed.
With such a definition of EVAL-WHEN, a [meta-circular] definition of DEFMACRO
might look like:
(DEFMACRO DEFMACRO (NAME BVL &BODY FORMS)
`(PROGN (EVAL-WHEN (COMPILE)
(COMPILER::NOTICE-DEFMACRO ',NAME ',BVL ',FORMS))
(EVAL-WHEN (EVAL LOAD)
(SETF (MACRO-FUNCTION ',NAME)
#'(LAMBDA (#:CALL #:ENV)
(COMPILER::DEFMACRO-HACK-ARGUMENTS ((#:CALL #:ENV) ,BVL)
,@FORMS))))))
This would imply:
- At toplevel in the compiler, the compiler would notice the definition.
- At toplevel in the compiler, the compiler would set things up to have the
compiled definition restored.
- In any non-top-level position, the behavioral equivalent of EVAL in a toplevel
environment would be done, so the macro would take effect at runtime.
My proposal is not designed to let you do
(LET ((X 3)) (DEFMACRO FOO () X))
but not by some flaw: I don't believe that this is appropriate.
Under my theory of EVAL-WHEN, the way you would define DEFUN to capture the
lexical environment (glossing the weird hairy implicit-block issue) is:
(DEFMACRO DEFUN (NAME BVL &BODY FORMS)
`(PROGN (EVAL-WHEN (COMPILE) (COMPILER::NOTICE-DEFUN ',NAME ',BVL ',FORMS))
(SETF #',NAME #'(LAMBDA ,BVL ,@FORMS))
',NAME))
This would imply:
- At toplevel in the compiler, the compiler would notice the definition.
- At toplevel in the compiler, the compiler would set things up to have the
compiled definition restored.
- In any non-top-level position, the compiler would not notice the definition
in a formal way, but it would compile it in the current lexical contour
and the definition would take place when the code was executed.
This would, therefore, permit
(LET ((X 3)) (DEFUN FOO () X))
and
(DEFUN INITIALIZE-FOO (X) (DEFUN FOO () X))
∂13-Jan-89 1454 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Jan 89 14:53:53 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 521325; Fri 13-Jan-89 17:52:09 EST
Date: Fri, 13 Jan 89 17:52 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-OBJECTS (Version 2)
To: CL-Cleanup@SAIL.STANFORD.EDU
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU, CL-Compiler@SAIL.STANFORD.EDU
Message-ID: <19890113225201.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Here is the updated version of this. Sorry it took so long.
I will bring a few copies of this with me to the meeting.
Issue: LOAD-OBJECTS
References: none
Related issues: LOAD-TIME-EVAL,
CONSTANT-COMPILABLE-TYPES,
CONSTANT-CIRCULAR-COMPILATION
Category: ADDITION
Forum: Cleanup
Edit history: Version 1, 2-Jan-89, by Moon (for discussion)
Version 2, 13-Jan-89, by Moon (draft updated from discussion)
Problem description:
Common Lisp doesn't provide any way to use an object of a user-defined
type (defined with DEFCLASS or DEFSTRUCT) as a constant in a program
compiled with COMPILE-FILE. The problem is that LOAD has to be able
to "reconstruct" an equivalent object when the compiled-code file is
loaded, but the programmer has no way to tell LOAD how to do that.
Proposal (LOAD-OBJECTS:MAKE-LOAD-FORM):
Define a new generic function named MAKE-LOAD-FORM, which takes one
argument and returns two values. The argument is an object that is
referenced as a constant or as a self-evaluating form in a file being
compiled by COMPILE-FILE. The objective is to enable LOAD to
construct an equivalent object.
The first value, called the "creation form," is a form that, when
evaluated at load time, should return an object that is equivalent to
the argument. The exact meaning of "equivalent" depends on the type
of object and is up to the programmer who defines a method for
MAKE-LOAD-FORM. This is the same type of equivalence discussed
in issue CONSTANT-COMPILABLE-TYPES.
The second value, called the "initialization form," is a form that,
when evaluated at load time, should perform further initialization of
the object. The value returned by the initialization form is ignored.
If the MAKE-LOAD-FORM method returns only one value, the
initialization form is NIL, which has no effect. If the object used
as the argument to MAKE-LOAD-FORM appears as a constant in the
initialization form, at load time it will be replaced by the
equivalent object constructed by the creation form; this is how the
further initialization gains access to the object.
Both the creation form and the initialization form can contain
references to objects of user-defined types (defined precisely below).
However, there must not be any circular dependencies in creation forms.
An example of a circular dependency is when the creation form for the
object X contains a reference to the object Y, and the creation form
for the object Y contains a reference to the object X. A simpler
example would be when the creation form for the object X contains
a reference to X itself. Initialization forms are not subject to
any restriction against circular dependencies, which is the entire
reason that initialization forms exist. See the example of circular
data structures below.
The creation form for an object is always evaluated before the
initialization form for that object. When either the creation form or
the initialization form references other objects of user-defined types
that have not been referenced earlier in the COMPILE-FILE, the
compiler collects all of the creation forms together and collects all
of the initialization forms together. All of the creation forms are
evaluated before any of the initialization forms. The order of
evaluation of the creation forms is unspecified except when the
ordering is forced by data dependencies. The order of evaluation of
the initialization forms is unspecified.
While these creation and initialization forms are being evaluated, the
objects are possibly in an uninitialized state, analogous to the state
of an object between the time it has been created by ALLOCATE-INSTANCE
and it has been processed fully by INITIALIZE-INSTANCE. Programmers
writing methods for MAKE-LOAD-FORM must take care in manipulating
objects not to depend on slots that have not yet been initialized.
It is unspecified whether LOAD calls EVAL on the forms or does some
other operation that has an equivalent effect. For example, the
forms might be translated into different but equivalent forms and
then evaluated, they might be compiled and the resulting functions
called by LOAD, or they might be interpreted by a special-purpose
interpreter different from EVAL. All that is required is that the
effect be equivalent to evaluating the forms.
COMPILE-FILE calls MAKE-LOAD-FORM on any object that is referenced as
a constant or as a self-evaluating form, if the object's metaclass is
STANDARD-CLASS, STRUCTURE-CLASS, any user-defined metaclass (not a
subclass of BUILT-IN-CLASS), or any of a possibly-empty
implementation-defined list of other metaclasses. COMPILE-FILE will
only call MAKE-LOAD-FORM once for any given object (compared with EQ)
within a single file.
It is valid for user programs to call MAKE-LOAD-FORM in other
circumstances.
The function MAKE-LOAD-FORM-USING-SLOTS can be useful in user-written
MAKE-LOAD-FORM methods. Its first argument is the object. Its
optional second argument is a list of the names of the slots to
preserve; it defaults to all of the local slots.
MAKE-LOAD-FORM-USING-SLOTS returns forms that construct an equivalent
object using MAKE-INSTANCE and SETF of SLOT-VALUE for slots with
values, or SLOT-MAKUNBOUND for slots without values, or using other
functions of equivalent effect. MAKE-LOAD-FORM-USING-SLOTS returns
two values, thus it can deal with circular structures.
The default MAKE-LOAD-FORM method for STANDARD-OBJECT signals an
error.
The default MAKE-LOAD-FORM method for STRUCTURE-OBJECT returns forms
that construct an equivalent structure based on the structure name and
the slot values. This might be written using
MAKE-LOAD-FORM-USING-SLOTS, but that is not required.
Examples:
;; Example 1
(defclass my-class ()
((a :initarg :a :reader my-a)
(b :initarg :b :reader my-b)
(c :accessor my-c)))
(defmethod shared-initialize ((self my-class) ignore &rest ignore)
(unless (slot-boundp self 'c)
(setf (my-c self) (some-computation (my-a self) (my-b self)))))
(defmethod make-load-form ((self my-class))
`(make-instance ',(class-name (class-of self))
:a ',(my-a self) :b ',(my-b self)))
In this example, an equivalent instance of my-class is reconstructed
by using the values of two of its slots. The value of the third slot
is derived from those two values.
Another way to write the last form in the above example would have been
(defmethod make-load-form ((self my-class))
(make-load-form-using-slots self '(a b)))
;; Example 2
(defclass my-frob ()
((name :initarg :name :reader my-name)))
(defmethod make-load-form ((self my-frob))
`(find-my-frob ',(my-name self) :if-does-not-exist :create))
In this example, instances of my-frob are "interned" in some way.
An equivalent instance is reconstructed by using the value of the
name slot as a key for searching existing objects. In this case
the programmer has chosen to create a new object if no existing
object is found; alternatively she could have chosen to signal an
error in that case.
;; Example 3
(defclass tree-with-parent () ((parent :accessor tree-parent)
(children :initarg :children)))
(defmethod make-load-form ((x tree-with-parent))
(values
;; creation form
`(make-instance ',(class-of x) :children ',(slot-value x 'children))
;; initialization form
`(setf (tree-parent ',x) ',(slot-value x 'parent))))
In this example, the data structure to be dumped is circular, because
each parent has a list of its children and each child has a reference
back to its parent. Suppose make-load-form is called on one object in
such a structure. The creation form creates an equivalent object and
fills in the children slot, which forces creation of equivalent
objects for all of its children, grandchildren, etc. At this point
none of the parent slots have been filled in. The initialization form
fills in the parent slot, which forces creation of an equivalent
object for the parent if it was not already created. Thus the entire
tree is recreated at load time. At compile time, MAKE-LOAD-FORM is
called once for each object in the true. All of the creation forms
are evaluated, in unspecified order, and then all of the
initialization forms are evaluated, also in unspecified order.
Rationale:
Only the programmer who designed a class can know the correct
way to reconstruct objects of that class at load time, therefore
the reconstruction should be controlled by a generic function.
Using EVAL as the interface for telling LOAD what to do provides
full generality.
MAKE-LOAD-FORM returns two values so that circular structures can
be handled. If CONSTANT-CIRCULAR-COMPILATION is rejected,
MAKE-LOAD-FORM will only return one value, although implementations
that make an extension to support circular constants will probably
also make the extension to accept two values from MAKE-LOAD-FORM.
A default method, such as one that makes an object whose class has the
same name and whose slots have equivalent contents, is not supplied
for DEFCLASS-defined objects, because this is inappropriate for many
objects and because it is easy to write for those objects where it is
appropriate. The function MAKE-LOAD-FORM-USING-SLOTS makes it even
easier to write.
MAKE-LOAD-FORM has a natural resemblance to PRINT-OBJECT, as a hook
for the programmer to control the system's actions.
Current practice:
Symbolics Flavors has something like this, but under a different name.
The name Symbolics uses is not suitable for standardization.
JonL reports that Lucid is getting more and more requests for this.
Cost to Implementors:
This seems like only a few one-line changes in the compiled-code
file writer and reader. MAKE-LOAD-FORM-USING-SLOTS is a couple
dozen lines of code, assuming the presence of the CLOS metaobject
protocol or an implementation-dependent equivalent.
Cost to Users:
None.
Cost of non-adoption:
Serious impairment of the ability to use extended-type objects. Each
implementation will probably make up its own version of this as an
extension.
Performance impact:
None.
Benefits:
See Cost of non-adoption.
Esthetics:
No significant positive or negative impact.
Discussion:
It would be possible to define an additional level of protocol that
allows multiple classes to contribute to the reconstruction of an
object, combining initialization arguments contributed by each class.
Since a user can easily define that in terms of MAKE-LOAD-FORM without
modifying the Lisp system, it is not being proposed now.
Any type that has a read syntax is likely to appear as a quoted
constant or inside a quoted constant. Pathnames are one example, user
programs often define others. Also many implementations provide a way
to create a compiled-code file full of data (rather than compiled Lisp
programs), and such data probably include extended-type objects.
Moon supports this. David Gray and John Rose made major contributions
to the discussion that produced this improved version 2 proposal.
∂13-Jan-89 1602 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Jan 89 16:02:32 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 521384; Fri 13-Jan-89 19:00:48 EST
Date: Fri, 13 Jan 89 19:00 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-OBJECTS (Version 2)
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CL-Cleanup@SAIL.STANFORD.EDU,
Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <19890113225201.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <890113190027.7.KMP@BOBOLINK.SCRC.Symbolics.COM>
This looks mostly very good, but ...
I'd like to see a name attached to the default function for making
structure load forms, since you're requiring it to exist anyway,
and also since there might be reason to need to revert to using it
in some structure class for which the method is shadowed by a
superior class that was not `thinking ahead.'
[I call this problem the `DESCRIBE problem,' since the analagous
problem comes up there, too.]
I also think there needs to be a rationale given to making these
functions not be the default. My personal feeling is that if it's
undefined for structures, it should be undefined for instances, and vice
versa. In my mind, they serve the same conceptual purpose, and differ
only in degree of efficiency and syntax of interface. For me, they do
not differ in weird ways like whether EQUAL or EQUALP should treat them
differently, or whether MAKE-LOAD-FORM should know how to dump them.
I think the argument you give for not having a default instance-dumping
strategy applies equally to struct-dumping, so if you're going to make
them differ, you need to say what your reasoning is.
∂13-Jan-89 1921 CL-Compiler-mailer issue SHARP-COMMA-CONFUSION
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 13 Jan 89 19:21:01 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA03148g; Fri, 13 Jan 89 19:16:23 PST
Received: by bhopal id AA08544g; Fri, 13 Jan 89 19:18:39 PST
Date: Fri, 13 Jan 89 19:18:39 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901140318.AA08544@bhopal>
To: masinter.pa@Xerox.COM
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu,
KMP@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: masinter.pa@Xerox.COM's message of 11 Jan 89 23:43 PST <890111-234404-11837@Xerox>
Subject: issue SHARP-COMMA-CONFUSION
re: It treats #, more like , than like #. and gives a consistent
interpretation of it.
Right. So now it is
(1) useless for those who thought they know how to use the former,
inherently broken definition of #, and
(2) redundant with the new special form LOAD-TIME-EVAL.
I agree with Kent and Sandra that fixing up #, like this -- which will
inevitably lead to these two undesirable results -- is the worst of all
the possible things we could do.
Having looked ahead in the mails - - I see there will be some
"quibbling" as to how to acknowledge that vendors will continue to
supply some of the deleted or deprecated features of Common Lisp 1984.
I think this will be a very serious issue sooon, so maybe we should
start a discussion under a new Subject heading?
-- JonL --
∂13-Jan-89 1936 CL-Compiler-mailer Re: Issue: LOAD-OBJECTS (Version 2)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Jan 89 19:36:04 PST
Received: by ti.com id AA21295; Fri, 13 Jan 89 19:07:05 CST
Received: from Kelvin by tilde id AA00249; Fri, 13 Jan 89 18:52:39 CST
Message-Id: <2809731258-5200907@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 13 Jan 89 18:54:18 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU, CL-Compiler@SAIL.STANFORD.EDU
Subject: Re: Issue: LOAD-OBJECTS (Version 2)
In-Reply-To: Msg of Fri, 13 Jan 89 17:52 EST from David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
This looks good. The only thing I have doubts about is:
> The function MAKE-LOAD-FORM-USING-SLOTS can be useful in user-written
> MAKE-LOAD-FORM methods. Its first argument is the object. Its
> optional second argument is a list of the names of the slots to
> preserve; it defaults to all of the local slots.
> MAKE-LOAD-FORM-USING-SLOTS returns forms that construct an equivalent
> object using MAKE-INSTANCE and SETF of SLOT-VALUE for slots with
> values, or SLOT-MAKUNBOUND for slots without values, or using other
> functions of equivalent effect.
Rather than having the second argument default to a list of all instance
slots, it might be better to consider two separate cases:
1. If a second argument is supplied, then MAKE-INSTANCE will be used to
create the object, (using INITIALIZE-INSTANCE to default the slot
values), and then the designated slots will be forced to
have the proper value.
2. Without a second argument, ALLOCATE-INSTANCE will be used to create
the object (without invoking INITIALIZE-INSTANCE or
SHARED-INITIALIZE), and then all the slots will be filled in.
If you are going to specify all of the slot values, then there shouldn't
be a need to compute default values, and it may be undesirable to invoke
INITIALIZE-INSTANCE -- for example, it might complain about missing
required arguments or perform undesired side-effects.
> The default MAKE-LOAD-FORM method for STANDARD-OBJECT signals an
> error.
Wouldn't it be permissible to just not have a default method, so that a
"no applicable method" error is signalled?
∂13-Jan-89 1938 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Jan 89 19:37:51 PST
Received: by ti.com id AA20827; Fri, 13 Jan 89 16:51:32 CST
Received: from Kelvin by tilde id AA27417; Fri, 13 Jan 89 16:31:48 CST
Message-Id: <2809722780-4691595@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 13 Jan 89 16:33:00 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: cperdue@Sun.COM (Cris Perdue)
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
In-Reply-To: Msg of Tue, 10 Jan 89 10:17:22 PST from cperdue@Sun.COM (Cris Perdue)
> Regardless of the disposition of COMPILER-LET, I think the proposal had
> better also say that *dump-circle* is rebound to its current value at least
> during COMPILE-FILE. That way a source file can (eval-when (compile)
> (setq *dump-circle* t)) if it contains circular structure.
That sounds like a good solution to me. If COMPILE-FILE binds it around
all passes of the compiler, then the compile-time evaluation will remain
in effect for all subsequent passes. The proposal should note that
COMPILER-LET is not an appropriate way to control this.
∂13-Jan-89 1939 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Jan 89 19:39:00 PST
Received: by ti.com id AA20835; Fri, 13 Jan 89 16:52:38 CST
Received: from Kelvin by tilde id AA27633; Fri, 13 Jan 89 16:41:32 CST
Message-Id: <2809723405-4729145@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 13 Jan 89 16:43:25 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cperdue@Sun.COM (Cris Perdue), cl-compiler@sail.stanford.edu
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
In-Reply-To: Msg of Tue, 10 Jan 89 11:26:23 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> I really dislike the idea of allowing it to be meaningful to tweak
> this variable on the fly during compilation.
But the analogy with *PRINT-CIRCLE* breaks down if you can't control it
where you need it. A program can do (LET ((*PRINT-CIRCLE* T)) ...) if
it knows it will be printing some circular lists, and similarly, a
program that uses circular constants should be able to declare that in
the program code itself. If this takes the form of "oh, by the way, you
have to manually set *DUMP-CIRCLE* before you can compile this file",
then the existence of such a flag becomes more of a booby trap than a
feature.
> In a
> multipass compiler, dumping of constants may not happen until much
> later than the processing of EVAL-WHEN forms. For example, you might
> not even look at constants until you've read in the code from the
> entire file and performed the required processing on top-level-forms.
Using the (EVAL-WHEN (COMPILE) (SETQ *DUMP-CIRCLE* T)) technique
shouldn't have any problem with this as long as you evaluate the SETQ
before you need to use *DUMP-CIRCLE* and leave it set for the remainder
of compilation.
> Plus, what happens if you try to coalesce a constant in created one
> place where *DUMP-CIRCLE* was true with one that was created in
> another place where *DUMP-CIRCLE* was false?
Assuming the compile-time evaluation happens in the first pass, then
subsequent passes will see the flag as being either true or false for
the entire file.
∂13-Jan-89 1942 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Jan 89 19:41:55 PST
Received: by ti.com id AA21028; Fri, 13 Jan 89 17:52:45 CST
Received: from Kelvin by tilde id AA28727; Fri, 13 Jan 89 17:31:41 CST
Message-Id: <2809726408-4909525@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 13 Jan 89 17:33:28 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
In-Reply-To: Msg of Tue, 10 Jan 89 12:44:04 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE:
>
> State that macro environment objects received with the &ENVIRONMENT
> argument of a macro function have indefinite extent.
That's fine for macro definitions, but this will not work for environments
containing class definitions. The compiler needs to be able to know when
those compile-time class definitions are no longer needed so that they can
be unlinked from the class data structures. How about a compromise that
says that environments have a dynamic extent corresponding to the
invocation of COMPILE or COMPILE-FILE, rather than the individual macro
expansion? That would permit the compiler to clean up classes while still
letting your macro example work.
This issue has a strong relationship with issue
SYNTACTIC-ENVIRONMENT-ACCESS since it proposes extending the use of
environments in ways that would make anything other than
MACRO-ENVIRONMENT-EXTENT:DYNAMIC difficult to retro-fit to existing
implementations.
∂13-Jan-89 2058 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 2)
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 13 Jan 89 20:58:12 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA04397; Fri, 13 Jan 89 20:59:34 PST
Received: from lukasiewicz.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA22496; Fri, 13 Jan 89 20:56:15 PST
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA18401; Fri, 13 Jan 89 20:58:49 PST
Date: Fri, 13 Jan 89 20:58:49 PST
From: jrose@Sun.COM (John Rose)
Message-Id: <8901140458.AA18401@lukasiewicz.sun.com>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: CL-Cleanup@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Fri, 13 Jan 89 17:52 EST <19890113225201.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue: LOAD-OBJECTS (Version 2)
...
The creation form for an object is always evaluated before the
initialization form for that object. When either the creation form or
the initialization form references other objects of user-defined types
that have not been referenced earlier in the COMPILE-FILE, the
compiler collects all of the creation forms together and collects all
of the initialization forms together. All of the creation forms are
evaluated before any of the initialization forms. The order of
evaluation of the creation forms is unspecified except when the
ordering is forced by data dependencies. The order of evaluation of
the initialization forms is unspecified.
...
Why does the proposal restrict the evaluation initialization forms to
such a late time? Data dependencies would allow an object X's
initialization form to be executed any time after X's creation form had
finished. Is there a reason to be more strict? I can't think of one,
but if there is one, it should be stated on the rationale.
Actually, it would be better (and no more difficult, it seems to me) to
be strict in the other direction: Objects should be initialized as early
as possible, and hence at a deterministic time. This would allow nodes
in non-circular structures to be built out of fully initialized subparts,
which is clearly something an application could need.
Here's what your paragraph would look like, given that point:
The creation form for an object X is always fully evaluated before the
initialization form for that object. This evaluation includes the
evaluation of the creation form of any user-defined object Y contained
in X's creation form, and will also include the evaluation of Y's
initialization form, if X and Y are not part of a circular chain of
initialization forms. Any circular substructures of X will be fully
initialized. Initialization forms of circular structures are
evaluated in an implementation-defined order, subject to the previous
restrictions. These rules are intended to ensure that initialization
follows creation as quickly as possible, subject to data flow.
Under these rules, noncircular data structures will be treated as if
all the initialization forms will immediately follow the creation
forms this way:
(eval `(let ((obj ,<creation-form>))
,(subst 'obj <original-object> <initialization-form>)
obj))
Furthermore, circular sub-structures will not impair the timely
initialization of non-circular containing structures. Such guarantees
will give programmers a sense of security in breaking out as much
processing as possible into the initialization form.
If this point of view is not adopted, a laissez-faire position is probably
better, and I think your paragraph above could be deleted, or rewritten thus:
The creation form for an object is always fully evaluated before the
initialization form for that object. This evaluation includes the
evaluation of creation forms of any user-defined objects contained in
the creation form, and may or may not include the evaluation of
initialization forms. However, when a "top-level object" is loaded,
all creation and initialization forms of that object must be fully
evaluated before any further loading actions are taken. These rules
are intended to allow implementations a high degree of freedom in
ordering the evaluation of creation and initialization forms, subject
to the requirements of data flow.
This paragraph needs to define the the specially-treated "top-level object",
which seems to be a concept implicit in your original paragraph. But I'd
rather see my first point adopted, and be done with top-level objects.
-- John
∂14-Jan-89 0334 CL-Compiler-mailer Issue COMPILER-DIAGNOSTICS, v8
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 14 Jan 89 03:33:30 PST
Date: Mon 9 Jan 89 18:53:50-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue COMPILER-DIAGNOSTICS, v8
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12461308829.25.IIM@ECLA.USC.EDU>
> (3) Require COMPILE-FILE to establish a condition handler. Add a
> :HANDLER keyword argument to COMPILE-FILE, which is a user condition
> handler function which is to be used during compilation. If the user
> handler is not supplied or declines to handle a condition, then the
> compiler's default handler will be invoked. Require the compiler
> to handle the ABORT restart by aborting the smallest feasible part
> of the compilation.
>
> ...
>
> (5) Clarify that COMPILE does not establish a condition handler. Instead,
> it uses whatever condition handler has been established in the
> environment from which it is called.
COMPILE-FILE and COMPILE should be allowed to establish whatever handlers they
want, with the requirement that they be written in a particular fashion. This
eliminates the need for a funky :handler argument which needs to handle all
condition types (possibly by just returning from the handler, thereby "refusing
to handle") because there isn't a place to associate a type with the handler.
The way you do this is to require that the compiler's handlers first resignal
the condition. Only if nobody outside handles the condition does the
compiler's handler really do anything. For example
(let ((error-count 0))
(handler-bind ((error
#'(lambda (condition)
;; keep track of how many errors we've had
(incf error-count)
;; allow caller to handle
(signal condition)
;; caller passed. print a message and abort some
;; part of the compilation.
(format *error-output* "~&*ERROR: ~A" condition)
(abort))))
...))
Using this scheme, the caller of COMPILE or COMPILE-FILE can set up whatever
handler environment he wants, with the expectation that the compiler will give
his handlers first crack at any conditions that are signaled.
For Current Practice, this is how IIM handles errors and such during
compilation (except that the restart we are currently using is not abort, but I
now think that may have been a mistake, and could easily be changed).
kab
-------
∂20-Jan-89 1259 CL-Compiler-mailer report from Kauai meeting
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 20 Jan 89 12:59:38 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA26757; Fri, 20 Jan 89 13:59:16 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA17344; Fri, 20 Jan 89 13:59:13 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901202059.AA17344@defun.utah.edu>
Date: Fri, 20 Jan 89 13:59:12 MST
Subject: report from Kauai meeting
To: cl-compiler@sail.stanford.edu
Following are my notes on what was decided at the Kauai meeting
relating to cl-compiler issues. I may have gotten confused about some
of the details, in which case I'd appreciate it if somebody
straightens me out. Once we all get unconfused, I will fix up the
passed issues to include the amendments and make them available.
These issues were brought up for a vote.
ALLOW-LOCAL-INLINE (v4)
Passed.
COMPILE-ENVIRONMENT-CONSISTENCY (v3)
Tabled for rewrite. The CLOS people had some objections that we will
have to work out with them, but I don't remember exactly what the
other complaints were.
DEFCONSTANT-SPECIAL (v3)
Passed w/amendment -- proposal now reads "Clarify that it is an error to
rebind...."
LOAD-TIME-EVAL (v8)
Passed w/amendments -- minor wording changes (I have them written on
a slide)
SHARP-COMMA-CONFUSION (v2)
Passed.
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS (v8)
Passed w/amendments -- the paragraphs on DEFCLASS, DEFGENERIC and
DEFMETHOD, and DEFINE-METHOD-COMBINATION were removed. We need to
consult with the CLOS people to clarify how these macros are
specified.
CONSTANT-MODIFICATION (v2)
Passed.
Here are some notes on other issues, from off-line discussions with
various people at the meeting. I will be sending out more details on
most of these in subsequent messages.
COMPILER-DIAGNOSTICS (v8)
COMPILER-VERBOSITY (v5)
Pierson has indicated he is willing to see the NOTICE type proposals
withdrawn, and COMPILER-DIAGNOSTICS rewritten to use STYLE-WARNING
instead.
CONSTANT-COMPILABLE-TYPES (v5)
The next version of the proposal probably won't require readtables to
be compilable, but there is still debate about interpreted functions.
QUOTE-MAY-COPY (v4)
The writeup for this issue will be totally rewritten as soon as I
have time to do it.
EVAL-WHEN-NON-TOP-LEVEL (v4)
JonL says he agrees with me that it is OK not to make EVAL-WHEN pass
top-level-ness through. There is some question as to whether changing
the nesting behavior of EVAL-WHEN really belongs in a separate issue.
COMPILER-LET-CONFUSION (v5)
Kim Barrett has come up with a clever trick which may satisfy Kent's
requirements but still allow us to remove COMPILER-LET.
MACRO-ENVIRONMENT-EXTENT (v1)
There was a suggestion from Gregor to allow &environment arguments
to have only dynamic extent, but provide a function to "copy" them.
DEFCONSTANT-NOT-WIRED (v5)
I think this issue is now dead, since you can get the required effect
by saying (defconstant foo (load-time-value ...)).
SYNTACTIC-ENVIRONMENT-ACCESS
Kim Barrett is trying to revive this issue.
-------
∂20-Jan-89 1333 CL-Compiler-mailer deadlines & priorities
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 20 Jan 89 13:33:26 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA27916; Fri, 20 Jan 89 14:33:07 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA17365; Fri, 20 Jan 89 14:33:05 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901202133.AA17365@defun.utah.edu>
Date: Fri, 20 Jan 89 14:33:04 MST
Subject: deadlines & priorities
To: cl-compiler@sail.stanford.edu
At the Kauai meeting it was made clear that anything we don't vote on
by the March meeting won't make it in to the initial draft of the
standard. That means we essentially have a month and a half left in
which to finish up our remaining issues. We will have to work very
hard and concentrate on those issues that are most crucial.
In my view, our first concern ought to be clarifying the things that
CLtL leaves unspecified and fixing obvious mistakes, with a somewhat
lower priority to the addition of new features. Here is a list of the
issues I think we should be working on hardest, grouped from the most
important to the less important.
COMPILE-ENVIRONMENT-CONSISTENCY
COMPILER-LET-CONFUSION
CONSTANT-COMPILABLE-TYPES
CONSTANT-CIRCULAR-COMPILATION
EVAL-WHEN-NON-TOP-LEVEL
DEFINING-MACROS-NON-TOP-LEVEL
QUOTE-MAY-COPY
COMPILED-FUNCTION-REQUIREMENTS
MACRO-ENVIRONMENT-EXTENT
COMPILER-DIAGNOSTICS
COMPILER-VERBOSITY
CONSTANT-COLLAPSING
I also think that issues SYNTACTIC-ENVIRONMENT-ACCESS and
MACRO-ENVIRONMENT-CREATOR are very important, but I am not sure
whether we will be able to resolve them in the time we have remaining.
In addition, the CLOS people seem to be assuming that we are going to
say something about using environment objects while making
compile-time side-effects happen, and I am even less certain that we
will be able both determine what it is that they want us to do and
figure out how to specify it in the time we have remaining.
I have one request to make from all of you. More than one person has
complained that the discussion lately has been far too rambling, to
the point where people have had a hard time understanding how it
relates to the proposals. Please, try to keep your comments more
focused on the issues at hand. In particular, if you have some
particular problem with the proposals, I'd like to see suggestions for
specific wording changes instead of just generic flaming.
-Sandra
-------
∂21-Jan-89 1916 CL-Compiler-mailer issue COMPILER-LET-CONFUSION
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 21 Jan 89 19:16:18 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA02231; Sat, 21 Jan 89 20:15:26 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA18001; Sat, 21 Jan 89 20:15:13 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901220315.AA18001@defun.utah.edu>
Date: Sat, 21 Jan 89 20:15:11 MST
Subject: issue COMPILER-LET-CONFUSION
To: kmp@stony-brook.scrc.symbolics.com
Cc: iim@ecla.usc.edu, cl-compiler@sail.stanford.edu
In an earlier message on this topic, you wrote:
> Suppose that instead of referencing the value as a special, you had
> an operator COMPILER-SYMBOL-VALUE to get its value. [That could be a
> function, macro, or special form.] I wouldn't have a problem calling
> a function to get this data because I still get to use the same basic
> `shape' of code. Also, uses of COMPILER-LET are rare enough that a
> bit of extra syntax is not overwhelming.
At the Hawaii meeting, Kim Barrett showed me a clever example of how
you can already get this effect using SYMBOL-MACROLET.
Where one would now write something like:
(compiler-let ((*foo* (new-value)))
... (some-macro) ...)
(defmacro some-macro ()
... *foo* ...)
one could instead use SYMBOL-MACROLET:
(symbol-macrolet ((*foo* (new-value)))
... (some-macro) ...)
(defmacro some-macro (&environment env)
... (symbol-macro-value '*foo* env) ...)
(defun symbol-macro-value (symbol env &optional default)
(multiple-value-bind (expansion macro-p) (macroexpand-1 symbol env)
(if macro-p expansion default)))
How does this strike you? I really like this approach, because it is
entirely lexical and avoids all the problems relating to the special
binding of COMPILER-LET. There will be some conversion necessary for
user code, but as you noted in your earlier message, the basic "shape"
of the code remains the same.
-Sandra
-------
∂21-Jan-89 1946 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 21 Jan 89 19:46:46 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA02403; Sat, 21 Jan 89 20:46:26 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA18017; Sat, 21 Jan 89 20:46:24 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901220346.AA18017@defun.utah.edu>
Date: Sat, 21 Jan 89 20:46:23 MST
Subject: issue EVAL-WHEN-NON-TOP-LEVEL
To: cl-compiler@sail.stanford.edu
In an off-line discussion at the Hawaii meeting, JonL agreed to
withdraw his objection about the bodies of EVAL-WHENs not being
top-level. However, it appears that some other people are having
problems with the idea of changing the nesting behavior of EVAL-WHEN
in an incompatible way, which makes me think that perhaps we should
separate the nesting issue from the non-top-level issue, or at least
offer an alternative proposal that doesn't mess with the nesting
behavior specified in CLtL.
To summarize the problem with nesting, suppose I have a whole bunch of
nested EVAL-WHENs at top-level:
(eval-when <situations-1>
(eval-when <situations-2>
...
(eval-when <situations-n>
<body>)
...))
The way EVAL-WHEN is specified in CLtL,
(1) Normal interpreter processing of <body> happens when -all- of
the nested EVAL-WHENs specify the EVAL situation.
(2) Normal compiler processing of <body> happens when -all- of the
nested EVAL-WHENs specify the LOAD situation.
(3) Compile-time evalution of <body> happens when -one- of the
EVAL-WHENs specifies the COMPILE situation, and -all- of the
ones nested inside of that specify either COMPILE or EVAL.
Our existing proposal does not change behaviors (1) or (2), but it changes
case (3):
- Compile-time evaluation of <body> happens when the outermost
EVAL-WHEN specifies the COMPILE situation and all of the ones
nested inside of that specify EVAL.
There are some other possibilities as well. For instance, this would
make the COMPILE situation symmetric with the other two:
- Compile-time evaluation of <body> happens when -all- of the
nested EVAL-WHENs specify the COMPILE situation.
And, this one would be somewhat more compatible with the CLtL description:
- Compile-time evaluation of <body> happens when the outermost
EVAL-WHEN specifies the COMPILE situation and all of the nested
ones specify either COMPILE or EVAL.
Does anybody have any thoughts on which of these behaviors is preferable?
I think they are all implementable. My own leaning is towards making
the COMPILE situation symmetric if we are going to change things at all.
-Sandra
-------
∂22-Jan-89 1325 CL-Compiler-mailer issue QUOTE-SEMANTICS, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 22 Jan 89 13:25:31 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA13966; Sun, 22 Jan 89 14:25:08 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA18383; Sun, 22 Jan 89 14:25:05 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901222125.AA18383@defun.utah.edu>
Date: Sun, 22 Jan 89 14:25:03 MST
Subject: issue QUOTE-SEMANTICS, version 1
To: cl-compiler@sail.stanford.edu
Here is a draft of this issue, which subsumes issue QUOTE-MAY-COPY. I
have renamed the issue and the proposals, and reworded things to make
it clear that any copying is performed by COMPILE or EVAL, not by
QUOTE.
There are three proposals in this writeup:
NO-COPYING is what used to be called QUOTE-MAY-COPY:NOT-EVAL-OR-COMPILE.
SAME-AS-COMPILE-FILE is what used to be called QUOTE-MAY-COPY:ALWAYS.
COPYING-ALLOWED-BUT-NO-CONSTRAINTS is basically QUOTE-MAY-COPY:ALWAYS,
but incorporates Kent's suggestion that there be no constraints on
what kinds of objects can appear in constants processed by COMPILE or
EVAL.
I have dropped what used to be QUOTE-MAY-COPY:NOT-EVAL, since I don't
have any record of anybody speaking out in favor of it. Also, at the
Hawaii meeting, Masinter mentioned that he knew of an implementation
where constants were copied in interpreted code (it happens when DEFUN
is macroexpanded).
My sense of the current opinion on this issue is that the argument to
maintain current practice is prevailing, and that it is extremely
unlikely that proposal NO-COPYING would be accepted.
New testimonials for the discussion section are solicited. To avoid
another round of endless religious wars on this issue, please keep
your comments short and to the point. If you still have a problem
with the wording of the proposal, I'll be happy to fix it provided
that you can be specific about how you want it changed.
-Sandra
Forum: Compiler
Issue: QUOTE-SEMANTICS
Subsumes: Issue QUOTE-MAY-COPY
References: CLtL p. 55, 78, 86, 143
Issue CONSTANT-COLLAPSING
Issue CONSTANT-COMPILABLE-TYPES
Issue CONSTANT-CIRCULAR-COMPILATION
Category: CLARIFICATION
Edit History: V1, 22 Jan 1989, Sandra Loosemore
Status: **DRAFT**
Problem Description:
Is it permissible for COMPILE and EVAL to coalesce or copy constants?
Are there constraints upon what kinds of objects may appear as
constants in code processed by COMPILE or EVAL, similar to those for
COMPILE-FILE?
CLtL p86 states that (QUOTE <x>) simply returns <x>. On p55 it is
mentioned that the only self-evaluating forms that may be copied are
numbers or characters. It is also stated that an implementation is
permitted to collapse (or coalesce) EQUAL constants "appearing in code
to be compiled" (p78), which is defined to mean self-evaluating forms
or objects contained in a QUOTE form (without reference to whether the
form is processed by EVAL, COMPILE, or COMPILE-FILE).
Because of its nature as a file processor, COMPILE-FILE generally must
cause copies of constants to be constructed when the compiled code is
loaded. In a number of existing Lisp implementations, COMPILE also
causes constant objects to be copied and/or coalesced. There is also
at least one implementation where constants are copied by EVAL in some
circumstances.
Proposal QUOTE-SEMANTICS:NO-COPYING:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is not permitted; the resulting program
must reference objects that are EQL to the corresponding objects in
the source code. The constraints on what kinds of objects may appear
as constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.
Rationale:
This proposal is consistent with what many people think of as the
"traditional" semantics for QUOTE. It gives users maximum flexibility
about what kinds of objects may appear as constants.
Proposal QUOTE-SEMANTICS:COPYING-ALLOWED-BUT-NO-CONSTRAINTS:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted. Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime. Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.
Any object may validly appear as a constant in code processed by EVAL
or COMPILE. The constraints on what kinds of objects may appear as
constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.
Rationale:
This proposal is the most consistent with the semantics stated in CLtL.
It gives users maximum flexibility about what kinds of objects may
appear as constants.
Proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted. Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime. Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.
The constraints on what kinds of objects may appear as constants
(described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply to EVAL and COMPILE as well as to
COMPILE-FILE.
Rationale:
This makes the rules for handling of constants consistent between
EVAL, COMPILE, and COMPILE-FILE. It gives implementors maximum
flexibility in handling constants in EVAL and COMPILE.
Current Practice:
Implementations in which COMPILE copies constants include PSL/PCLS and
Kyoto Common Lisp. In Lucid Common Lisp, constants are not normally
copied by COMPILE, but since COMPILE does coalesce constants, it may
cause QUOTE to return an object which is not EQL to the object which
appeared in the source code.
There is known to be at least one implementation where expanding the
DEFUN macro causes all constants in the body of the function to be
copied.
Cost to implementors:
Proposal NO-COPYING would involve a significant cost in those
implementations where constants are now copied or coalesced by EVAL
and COMPILE. Some implementations would also require substantial
changes to support proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS. The
aspect that is likely to cause the most problems is that, in some
implementations, the garbage collector assumes that constants
referenced in compiled code have been copied to read-only storage and
do not need to be scanned or relocated.
Proposal SAME-AS-COMPILE-FILE has no adoption cost above what is
required to support issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION.
Cost to users:
Proposals COPYING-ALLOWED-BUT-NO-CONSTRAINTS and SAME-AS-COMPILE-FILE
may break some existing programs that assume constants in code
processed by EVAL or COMPILE are always EQL to the corresponding
objects in the source code. Proposal SAME-AS-COMPILE-FILE may also
break existing programs that depend on referencing "undumpable"
constants in code processed by EVAL or COMPILE. In both cases,
however, the behavior is already nonportable. Both proposals would
permit implementations in which these programs now work to continue to
provide their existing behavior.
Benefits:
The semantics of QUOTE are clarified.
Discussion:
This issue subsumes issue QUOTE-MAY-COPY, which caused a very lengthy
debate on the cl-compiler mailing list.
Loosemore supports proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE,
since it requires essentially no conversion cost for implementors and
does not break any user programs that are not already nonportable.
-------
∂23-Jan-89 1000 CL-Compiler-mailer Re: deadlines & priorities
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 23 Jan 89 10:00:20 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA20316; Mon, 23 Jan 89 10:01:41 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA17341; Mon, 23 Jan 89 09:58:20 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA21861; Mon, 23 Jan 89 09:59:26 PST
Date: Mon, 23 Jan 89 09:59:26 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901231759.AA21861@clam.sun.com>
To: sandra%defun@cs.utah.edu
Subject: Re: deadlines & priorities
Cc: cl-compiler@sail.stanford.edu
> Please, try to keep your comments more
> focused on the issues at hand. In particular, if you have some
> particular problem with the proposals, I'd like to see suggestions for
> specific wording changes instead of just generic flaming.
Hear, hear! Another approach that may help in some cases for
keeping discussion focussed is making a short, succinct list
of goals.
∂23-Jan-89 1152 CL-Compiler-mailer DEFMETHOD compile-time processing
Received: from ti.com by SAIL.Stanford.EDU with TCP; 23 Jan 89 11:52:44 PST
Received: by ti.com id AA28832; Mon, 23 Jan 89 13:52:14 CST
Received: from dsg by tilde id AA23248; Mon, 23 Jan 89 13:38:15 CST
Received: From Kelvin By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 23 Jan 89 11:15:29 CST
Message-Id: <2810567730-15432385@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 23 Jan 89 11:15:30 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Common-Lisp-Object-System@SAIL.Stanford.edu
Cc: CL-Compiler@SAIL.Stanford.edu
Subject: DEFMETHOD compile-time processing
In the Meta Object Protocol draft number 10 [89-003], on page 3-16 it says
that
"At compile time: ... (5) The method function is computed by
evaluating the special form (FUNCTION <lambda>) in the lexical
environment of the DEFMETHOD. ... (7) The function ADD-METHOD is
called ..."
This isn't going to work. You can install the function at load
time in its lexical environment, or you can install it at compile time in
the null lexical environment, but you can't evaluate something at
compile-time in its run-time lexical environment.
Possible remedies include:
* Do the compile-time call to ADD-METHOD only if the DEFMETHOD appears at
top-level in a null lexical environment. This would be consistent with
the treatment of DEFMACRO in proposal DEFINING-MACROS-NON-TOP-LEVEL.
* Don't ever do a compile-time call to ADD-METHOD. I haven't seen a
reason why methods would need to be installed in the compile-time
environment. Apparently at least some information about generic
function definitions needs to be remembered for use when invoking
MAKE-METHOD-LAMBDA, but that wouldn't require being able to actually
call the generic function at compile-time.
∂23-Jan-89 1153 CL-Compiler-mailer Re: report from Kauai meeting
Received: from ti.com by SAIL.Stanford.EDU with TCP; 23 Jan 89 11:53:39 PST
Received: by ti.com id AA28849; Mon, 23 Jan 89 13:52:30 CST
Received: from dsg by tilde id AA23290; Mon, 23 Jan 89 13:38:52 CST
Received: From Kelvin By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 23 Jan 89 12:07:29 CST
Message-Id: <2810570843-15619444@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 23 Jan 89 12:07:23 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: report from Kauai meeting
In-Reply-To: Msg of Fri, 20 Jan 89 13:59:12 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> DEFCONSTANT-NOT-WIRED (v5)
> I think this issue is now dead, since you can get the required effect
> by saying (defconstant foo (load-time-value ...)).
It's not obvious that DEFCONSTANT should have special handling for this
idiom, and even so, that still doesn't prevent the value from being wired
in when compiling other files after the file containing the DEFCONSTANT is
loaded.
∂23-Jan-89 1155 CL-Compiler-mailer Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Jan 89 11:54:36 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA04982; Mon, 23 Jan 89 12:53:07 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA18930; Mon, 23 Jan 89 12:52:52 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901231952.AA18930@defun.utah.edu>
Date: Mon, 23 Jan 89 12:52:50 MST
Subject: Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Mon, 23 Jan 89 13:49 EST
> Assuming the vote on DECLARATION-SCOPE is not likely to be reversed, I
> think DEFINING-MACROS-NON-TOP-LEVEL needs to be modified to treat the
> body of LOCALLY as top-level. If this requires changing LOCALLY from a
> macro to a special form, so be it.
I don't think that adding LOCALLY to the list of forms that must pass
top-level-ness through would be a problem. I don't see any great need
to change it to be a special form, either.
Thanks for pointing out this problem.
-Sandra
-------
∂23-Jan-89 1525 CL-Compiler-mailer Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Jan 89 15:25:03 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 525523; Mon 23-Jan-89 17:44:04 EST
Date: Mon, 23 Jan 89 17:43 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
To: sandra%defun@cs.utah.edu
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, cl-compiler@sail.stanford.edu
In-Reply-To: <8901231952.AA18930@defun.utah.edu>
Message-ID: <890123174357.0.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Mon, 23 Jan 89 12:52:50 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Assuming the vote on DECLARATION-SCOPE is not likely to be reversed, I
> think DEFINING-MACROS-NON-TOP-LEVEL needs to be modified to treat the
> body of LOCALLY as top-level. If this requires changing LOCALLY from a
> macro to a special form, so be it.
I don't think that adding LOCALLY to the list of forms that must pass
top-level-ness through would be a problem. I don't see any great need
to change it to be a special form, either. ...
If you don't make it a special form, then MACROEXPAND can change its semantics.
[eg, if LOCALLY expands into LET, but LET is not something that works at toplevel.]
Currently, I don't think that's permitted -- MACROEXPAND is normally a
semantics-preserving operation. I think Moon is right that adding LOCALLY to
that list would seem to require that it be implemented as a special form.
∂24-Jan-89 0257 CL-Compiler-mailer report from Kauai meeting
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 24 Jan 89 02:56:56 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01248g; Tue, 24 Jan 89 02:52:14 PST
Received: by bhopal id AA04312g; Tue, 24 Jan 89 02:54:36 PST
Date: Tue, 24 Jan 89 02:54:36 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901241054.AA04312@bhopal>
To: sandra%defun@cs.utah.edu
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Fri, 20 Jan 89 13:59:12 MST <8901202059.AA17344@defun.utah.edu>
Subject: report from Kauai meeting
re: CONSTANT-COMPILABLE-TYPES (v5)
The next version of the proposal probably won't require readtables to
be compilable, but there is still debate about interpreted functions.
Well, we did squeak in an amendment to the EQUAL-STRUCTURE fiasco that
said EQUALP will descend hash-tables using the "rule of Rose". So why
don't we let them be compilable now?
Conversely, defstruct instances got retracted to comparison by EQ,
simply because of the lack of a generic EQUAL and EQUALP proposal.
Similarly, non-built-in defstruct instances will probably have to be
compiled out via the mechanisms of the LOAD-OBJECTS proposal, since their
semantics are now becoming thoroughly intermixed with clos instances
-- JonL --
∂24-Jan-89 0853 CL-Compiler-mailer Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
Received: from ti.com by SAIL.Stanford.EDU with TCP; 24 Jan 89 08:53:19 PST
Received: by ti.com id AA02823; Tue, 24 Jan 89 10:51:49 CST
Received: from Kelvin by tilde id AA15472; Tue, 24 Jan 89 10:45:47 CST
Message-Id: <2810652537-4012647@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Tue, 24 Jan 89 10:48:57 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM,
cl-compiler@sail.stanford.edu
Subject: Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
In-Reply-To: Msg of Mon, 23 Jan 89 17:43 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> I don't think that adding LOCALLY to the list of forms that must pass
> top-level-ness through would be a problem. I don't see any great need
> to change it to be a special form, either. ...
>
> If you don't make it a special form, then MACROEXPAND can change its semantics.
> [eg, if LOCALLY expands into LET, but LET is not something that works at toplevel.]
> Currently, I don't think that's permitted -- MACROEXPAND is normally a
> semantics-preserving operation. I think Moon is right that adding LOCALLY to
> that list would seem to require that it be implemented as a special form.
An alternative would be to say that LET passes through "top-level-ness" when
its binding list is NIL.
∂24-Jan-89 0928 CL-Compiler-mailer DEFMETHOD compile-time processing
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 24 Jan 89 09:28:47 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01394g; Tue, 24 Jan 89 09:23:52 PST
Received: by challenger id AA18054g; Tue, 24 Jan 89 09:19:45 PST
Date: Tue, 24 Jan 89 09:19:45 PST
From: Patrick Dussud <dussud@lucid.com>
Message-Id: <8901241719.AA18054@challenger>
To: Gray@DSG.csc.ti.com
Cc: Common-Lisp-Object-System@SAIL.Stanford.edu, CL-Compiler@SAIL.Stanford.edu
In-Reply-To: David N Gray's message of Mon, 23 Jan 89 11:15:30 CST <2810567730-15432385@Kelvin>
Subject: DEFMETHOD compile-time processing
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 23 Jan 89 11:15:30 CST
From: David N Gray <Gray@DSG.csc.ti.com>
In the Meta Object Protocol draft number 10 [89-003], on page 3-16 it says
that
"At compile time: ... (5) The method function is computed by
evaluating the special form (FUNCTION <lambda>) in the lexical
environment of the DEFMETHOD. ... (7) The function ADD-METHOD is
called ..."
This isn't going to work. You can install the function at load
time in its lexical environment, or you can install it at compile time in
the null lexical environment, but you can't evaluate something at
compile-time in its run-time lexical environment.
you're right.
The general issue that we try to address is that it should be possible for
some implementations to precompute a certain number of characteristic of CLOS
programs at compile-file time. These precomputation involve metaobjects
(looking at user class definitions, method object, generic functions) in a
state that should be close enough to their state when the program is loaded in
the remote environment. It is not generally possible to simulate the remote
environment as far as running remote code. Therefore, precomputation at
compile time, by doing metaprogramming on remote environment objects is more
restrictive that doing metaprogramming on local environment objects. However,
we don't want to introduce two distinct metaprogrammings. Chapter 3 is trying
to unify remote and local metaprogramming. All the side effect that are done
when the program is loaded, is simulated in the remote environment(
Add-method, ensure-class...). As Gray noticed, it does not always work. In
particular, we should acknowledge the difference as far as function objects
are concerned: Local function object can be executed, remote functions can
only be looked at.
Possible remedies include:
* Do the compile-time call to ADD-METHOD only if the DEFMETHOD appears at
top-level in a null lexical environment. This would be consistent with
the treatment of DEFMACRO in proposal DEFINING-MACROS-NON-TOP-LEVEL.
I don't consider this solution very satisfying, because it hides the problem.
It is possible to represent functions for the remote environment by normal
functions if the lexical environment is null, but still, they can't be
executed. The problem remains.
* Don't ever do a compile-time call to ADD-METHOD. I haven't seen a
reason why methods would need to be installed in the compile-time
environment. Apparently at least some information about generic
function definitions needs to be remembered for use when invoking
MAKE-METHOD-LAMBDA, but that wouldn't require being able to actually
call the generic function at compile-time.
This will lead to two different metaprogramming styles. Note that this is more
or less what Flavors does. It is workable, but not pretty. Maybe a better
solution is to standardize a representation for objects in the remote
environment, and have the compile-file time expansion create them. Add-method
and such work as before, function slots don't always contain real functions.
Patrick.
∂24-Jan-89 0943 CL-Compiler-mailer issue DEFCONSTANT-SPECIAL, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Jan 89 09:43:37 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA05321; Tue, 24 Jan 89 10:42:13 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA19556; Tue, 24 Jan 89 10:42:08 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901241742.AA19556@defun.utah.edu>
Date: Tue, 24 Jan 89 10:42:07 MST
Subject: issue DEFCONSTANT-SPECIAL, version 4
To: cl-compiler@sail.stanford.edu
Here is the amended version that was approved at the Hawaii meeting.
Forum: Compiler
Issue: DEFCONSTANT-SPECIAL
References: CLtL p. 68-69, 55-56
Issue DEFCONSTANT-NOT-WIRED
Issue PROCLAIM-LEXICAL
Issue SYNTACTIC-ENVIRONMENT-ACCESS
Issue SPECIAL-VARIABLE-TEST
Category: CLARIFICATION
Edit History: V1, 15 Nov 1988, Sandra Loosemore
V2, 22 Nov 1988, Sandra Loosemore
V3, 30 Dec 1988, Sandra Loosemore
V4, 23 Jan 1989, Sandra Loosemore (amendment)
Problem Description:
It is unclear whether DEFCONSTANT is supposed to proclaim the variable
SPECIAL. Page 56 says that symbols defined by DEFCONSTANT "may not be
further assigned to or bound". Page 69 says that "further assignment
to or binding of that special variable is an error" but permits
compilers to "choose to issue warnings about bindings of the lexical
variable of the same name". Does this mean that it is legal (but
perhaps only questionable style) to lexically rebind constants? If
so, this would seem to imply that they must not be proclaimed SPECIAL
(since CLtL provides no way to override a SPECIAL proclamation).
Some people think that DEFCONSTANT is supposed to proclaim the
variable SPECIAL because CLtL says that DEFVAR does, and that
DEFPARAMETER is like DEFVAR, and DEFCONSTANT is like DEFPARAMETER.
Also, the use of the phrase "that special variable" rather than "the
special variable of the same name" might indicate that the variable
really is supposed to be special.
Proposal DEFCONSTANT-SPECIAL:DOESNT-MATTER:
Clarify that it is an error to rebind constant symbols as either
lexical or special variables. (In other words, a reference to a
symbol declared with DEFCONSTANT always refers to its global value.)
Rationale:
Clarifying that lexical rebinding (as well as special rebinding) of
constants "is an error" seems to be the behavior that most users
expect. One serious problem that might arise from allowing constants
to be rebound lexically is that it would not be reliable to include
symbolic constants in macro expansions, because the user might have
rebound them to something else.
Current Practice:
Most implementations apparently proclaim the variable special anyway.
Cost to implementors:
Minor.
Cost to users:
Probably none. Since many implementations do proclaim the variable to
be special (while at the same time forbidding special binding), there
is probably no user code that depends upon lexical rebinding of
DEFCONSTANTs.
Benefits:
An area of confusion in the language is removed.
Discussion:
This issue is primarily a documentation clarification. It arose
during a discussion of what the DEFCONSTANT macro might expand into.
As far as users are concerned, it makes no difference whether
constants are special or lexical, as long as all rebinding is
prohibited. The only situation where the distinction might become
important is if a function is added to the language to test whether a
variable has been proclaimed special.
The "problem description" section of the writeup on issue
PROCLAIM-LEXICAL (version 8) also appears to assume that constants
declared with DEFCONSTANT are not special.
-------
∂24-Jan-89 0944 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 9
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Jan 89 09:44:50 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA05467; Tue, 24 Jan 89 10:43:26 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA19568; Tue, 24 Jan 89 10:43:22 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901241743.AA19568@defun.utah.edu>
Date: Tue, 24 Jan 89 10:43:20 MST
Subject: issue LOAD-TIME-EVAL, version 9
To: cl-compiler@sail.stanford.edu
This version incorporates the amendments made at the Hawaii meeting.
Forum: Compiler
Issue: LOAD-TIME-EVAL
References: #, (p. 356), (EVAL-WHEN (LOAD) ...) (p. 69-70)
issue SHARP-COMMA-CONFUSION
Category: ADDITION
Edit history: 06-Jun-87, Version 1 by James Kempf
17-Jul-87, Version 2 by James Kempf
12-Nov-87, Version 3 by Pitman (alternate direction)
01-Feb-88, Version 4 by Moon
(from version 2 w/ edits suggested by Masinter)
06-Jun-88, Version 5 by Pitman
(fairly major overhaul, merging versions 3 and 4)
21-Sep-88, Version 6 by Moon (stripped down)
17-Oct-88, Version 7 by Loosemore (change direction again)
30-Dec-88, Version 8 by Loosemore (tweaks)
23-Jan-89, Version 9 by Loosemore (amendments)
Problem description:
Common Lisp provides reader syntax (#,) which allows the programmer
to designate that a particular expression within a program is to be
evaluated early (at load time) but to later be treated as a constant.
Unfortunately, no access to this capability is available to programs
which construct other programs without going through the reader.
Some computations can be deferred until load time by use of EVAL-WHEN,
but since EVAL-WHEN must occur only at toplevel, and since the nesting
behavior of EVAL-WHEN is quite unintuitive, EVAL-WHEN is not a general
solution to the problem of load-time computation of program constants.
Proposal (LOAD-TIME-EVAL:R**2-NEW-SPECIAL-FORM):
Add a new special form, LOAD-TIME-VALUE, which has the following
contract:
LOAD-TIME-VALUE form &optional read-only-p [Special Form]
LOAD-TIME-VALUE provides a mechanism for delaying evaluation of <form>
until the expression is in the "runtime" environment.
If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
performs normal semantic processing such as macro expansion but
arranges for the evaluation of <form> to occur at load time in a null
lexical environment, with the result of this evaluation then being
treated as an immediate quantity at run time. It is guaranteed that
the evaluation of <form> will take place only once when the file is
loaded, but the order of evaluation with respect to the "evaluation"
of top-level forms in the file is unspecified.
If a LOAD-TIME-VALUE expression appears within a function compiled
with COMPILE, the <form> is evaluated at compile time in a null lexical
environment. The result of this compile-time evaluation is treated as
an immediate quantity in the compiled code.
In interpreted code, <form> is evaluated (by EVAL) in a null
lexical environment, and one value is returned. Implementations which
implicitly compile (or partially compile) expressions passed to
EVAL may evaluate the <form> only once, at the time this
compilation is performed. This is intentionally similar to the
freedom which implementations are given for the time of expanding
macros in interpreted code.
Note that, in interpreted code, there is no guarantee as to when
evaluation of <form> will take place, or the number of times the
evaluation will be performed. Since successive evaluations of the
same LOAD-TIME-VALUE expression may or may not result in an evaluation
which returns a "fresh" object, destructive side-effects to the
resulting object may or may not persist from one evaluation to the
next. It is safest to explicitly initialize the object returned by
LOAD-TIME-VALUE, if it is later modified destructively.
Implementations must guarantee that each reference to a
LOAD-TIME-VALUE expression results in at least one evaluation of its
nested <form>. For example,
(DEFMACRO CONS-SELF (X)
`(CONS ,X ,X))
(CONS-SELF (LOAD-TIME-VALUE (COMPUTE-IT)))
must perform two calls to COMPUTE-IT; although there is only one
unique LOAD-TIME-VALUE expression, there are two distinct references
to it.
In the case of a LOAD-TIME-VALUE form appearing in a quoted expression
passed to EVAL, each call to EVAL must result in a new evaluation of
<form>. For example,
(DEFVAR X 0)
(DEFUN FOO () (EVAL '(LOAD-TIME-VALUE (INCF X))))
is guaranteed to increment X each time FOO is called, while
(DEFUN FOO () (LOAD-TIME-VALUE (INCF X)))
may cause X to be evaluated only once.
The READ-ONLY-P argument designates whether the result can be considered
read-only constant. If NIL (the default), the result must be considered
ordinary, modifiable data. If T, the result is a read-only quantity
which may, as appropriate, be copied into read-only space and/or shared
with other programs. (Because this is a special form, this argument is
-not- evaluated and only the literal symbols T and NIL are permitted.)
Rationale:
LOAD-TIME-VALUE is a special form rather than a function or macro
because it requires special handling by the compiler.
Requiring the compiler to perform semantic processing such as macro
expansion on the nested <form>, rather than delaying all such processing
until load time, has the advantages that fewer macro libraries may need
to be available at load time, and that loading may be faster and result
in less consing due to macroexpansion. If users really want to delay
macroexpansion to load time, this can be done with an explicit call to
EVAL, e.g.
(LOAD-TIME-VALUE (EVAL '(MY-MACRO)))
Allowing the same LOAD-TIME-VALUE to cause its nested <form> to be
evaluated more than once makes simplifies its implementation in
interpreters which do not perform a preprocessing code walk. It also
makes the rules for the time of its processing analogous to those
for macro expansion.
This proposal explicitly does -not- tie LOAD-TIME-VALUE to the #,
read macro. Doing so would be an incompatible change to the definition
of #, (which is reliably useful only -inside- quoted structure,
while LOAD-TIME-VALUE must appear -outside- quoted structure in a
for-evaluation position).
The requirement that LOAD-TIME-VALUE expressions be evaluated once per
reference (rather than once per unique expression) prevents problems
that could result by performing destructive side-effects on a value
that is unexpectedly referenced in more than one place.
Current Practice:
This is an addition to the language and has not yet been implemented.
Cost to Implementors:
In compiled code, (LOAD-TIME-VALUE <form>) is similar to
'#,<form>. Most implementations can probably make use of the same
mechanism they use to handle #, to handle LOAD-TIME-VALUE. Note that
#, does not currently provide a mechanism for dealing with
non-read-only-ness.
Implementing LOAD-TIME-VALUE in the interpreter should be fairly
straightforward, since one simply needs to evaluate the <form> in the
null lexical environment. Implementations that use a preprocessing
code walk in the interpreter to perform macro expansion could process
LOAD-TIME-VALUE forms at that time.
Some code-walkers would have to be taught about this new
special form. Such changes would likely be trivial.
Cost to Users:
Some code-walkers would have to be taught about this new
special form. Such changes would likely be trivial.
Benefits:
Users are given a mechanism that to force evaluation to be delayed
until load time that does not rely on a feature of the reader.
Discussion:
Earlier versions (up to version 7) of this proposal stated that
all semantic processing of the LOAD-TIME-VALUE form should be postponed
until load time.
The semantics of LOAD-TIME-VALUE would be simplified considerably if
the READ-ONLY-P argument were removed and destructive operations on
the result of evaluating <form> prohibited. However, some people feel
that the ability to destructively modify the value is an essential
feature to include.
"Collapsing" of multiple references to the same LOAD-TIME-VALUE
expression could be allowed for read-only situations, but it seems
like it would be more confusing to make it legal in some situations
and not in others.
A number of other alternatives have been considered on this issue,
including:
- A proposal for a new special form that would force evaluation of
the <form> to happen only once. This was rejected because of
implementation difficulties.
- A proposal to add a function making the "magic cookie" used by #,
available to user code. The current proposal does not prevent such
a function from being added, but this approach appeared to have
less support than making the hook available as a new special form.
- A proposal to remove #, entirely (issue SHARP-COMMA-CONFUSION).
- A suggestion to change the behavior of (EVAL-WHEN (LOAD) ...).
Kent Pitman says:
Although I'm willing to take multiple evaluation in the interpreter
as a compromise position, I would like it mentioned in the discussion
that this was only an expedient to getting this issue accepted at all,
and that I'm not really happy about it. I have said that I think a
number of our lingering problems (with EVAL-WHEN, COMPILER-LET, and
this -- for example) are due to the presence of interpreters which do
not do a semantic-prepass at a known time. If I had my way, we would
require a semantic pre-pass and we would then be able to forbid
multiple evaluations even in the interpreter.
-------
∂24-Jan-89 0946 CL-Compiler-mailer issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, v9
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Jan 89 09:46:02 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA05554; Tue, 24 Jan 89 10:44:34 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA19579; Tue, 24 Jan 89 10:44:30 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901241744.AA19579@defun.utah.edu>
Date: Tue, 24 Jan 89 10:44:29 MST
Subject: issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS, v9
To: cl-compiler@sail.stanford.edu
This is the version that was passed at the Hawaii meeting.
Forum: Compiler
Issue: COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
References: CLtL pages 66-70, 143
Category: CLARIFICATION
Edit history: V1, 07 Oct 1987 Sandra Loosemore
V2, 15 Oct 1987 Sandra Loosemore
V3, 15 Jan 1988 Sandra Loosemore
V4, 06 May 1988 Sandra Loosemore
V5, 20 May 1988 Sandra Loosemore
V6, 09 Jun 1988 Sandra Loosemore
V7, 16 Dec 1988 Sandra Loosemore
(Comments from Pitman, change DEFCONSTANT, etc.)
V8, 31 Dec 1988 Sandra Loosemore
(CLOS additions, etc.)
V9, 23 Jan 1989 Sanrda Loosemore
(remove the CLOS additions again)
Problem Description:
Standard programming practices assume that, when calls to defining
macros such as DEFMACRO and DEFVAR are processed by COMPILE-FILE,
certain side-effects occur that affect how subsequent forms in the
file are compiled. However, these side-effects are not mentioned in
CLtL, except for a passing mention that macro definitions must be
``seen'' by the compiler before it can compile calls to those macros
correctly. In order to write portable programs, users must know
exactly which defining macros have compile-time side-effects and what
those side-effects are.
Inter-file compilation dependencies are distinct from, and not
addressed by, this issue.
Proposal: COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY
(1) Clarify that defining macros such as DEFMACRO or DEFVAR, appearing
within a file being processed by COMPILE-FILE, normally have
compile-time side effects which affect how subsequent forms in the
same file are compiled. A convenient model for explaining how these
side effects happen is that the defining macro expands into one or
more EVAL-WHEN forms, and that the calls which cause the compile-time
side effects to happen appear in the body of an (EVAL-WHEN (COMPILE)
...) form.
(2) The affected defining macros and their specific side effects are
as follows. In each case, it is identified what users must do to
ensure that their programs are conforming, and what compilers must do
in order to correctly process a conforming program.
DEFTYPE: Users must ensure that the body of a DEFTYPE form is
evaluable at compile time if the type is referenced in subsequent type
declarations. The compiler must ensure that the DEFTYPE'd type
specifier is recognized in subsequent type declarations. If the
expansion of a type specifier is not defined fully at compile time
(perhaps because it expands into an unknown type specifier or a
SATISFIES of a named function that isn't defined in the compile-time
environment), an implementation may ignore any references to this type
in declarations and/or signal a warning.
DEFMACRO, DEFINE-MODIFY-MACRO: The compiler must store macro
definitions at compile time, so that occurrences of the macro later on
in the file can be expanded correctly. Users must ensure that the
body of the macro is evaluable at compile time if it is referenced
within the file being compiled.
DEFUN: DEFUN is not required to perform any compile-time side effects.
In particular, DEFUN does not make the function definition available
at compile time. An implementation may choose to store information
about the function for the purposes of compile-time error-checking
(such as checking the number of arguments on calls), or to enable the
function to be expanded inline.
DEFVAR, DEFPARAMETER: The compiler must recognize that the variables
named by these forms have been proclaimed special. However, it must
not evaluate the initial value form or SETQ the variable at compile
time.
DEFCONSTANT: The compiler must recognize that the symbol names a
constant. An implementation may choose to evaluate the value-form at
compile time, load time, or both. Therefore users must ensure that
the value-form is evaluable at compile time (regardless of whether or
not references to the constant appear in the file) and that it always
evaluates to the same value.
DEFSETF, DEFINE-SETF-METHOD: The compiler must make SETF methods
available so that it may be used to expand calls to SETF later on in
the file. Users must ensure that the body of DEFINE-SETF-METHOD and
the complex form of DEFSETF are evaluable at compile time if the
corresponding place is referred to in a subsequent SETF in the same
file. The compiler must make these SETF methods available to
compile-time calls to GET-SETF-METHOD when its environment argument is
a value received as the &ENVIRONMENT parameter of a macro.
DEFSTRUCT: The compiler must make the structure type name recognized
as a valid type name in subsequent declarations (as for DEFTYPE) and
make the structure slot accessors known to SETF. In addition, the
compiler must save enough information about the structure type so that
further DEFSTRUCT definitions can :INCLUDE a structure type defined
earlier in the file being compiled. The functions which DEFSTRUCT
generates are not defined in the compile time environment, although
the compiler may save enough information about the functions to code
subsequent calls inline. The #S reader syntax may or may not be
available at compile time.
DEFINE-CONDITION: The rules are essentially the same as those for
DEFSTRUCT; the compiler must make the condition type recognizable as a
valid type name, and it must be possible to reference the condition
type as the parent-type of another condition type in a subsequent
DEFINE-CONDITION in the file being compiled.
DEFPACKAGE: All of the actions normally performed by this macro at load
time must also be performed at compile time.
(3) The compile-time side effects may cause information about the
definition to be stored differently than if the defining macro had
been processed in the "normal" way (either interpretively or by loading
the compiled file).
In particular, the information stored by the defining macros at
compile time may or may not be available to the interpreter (either
during or after compilation), or during subsequent calls to COMPILE or
COMPILE-FILE. For example, the following code is nonportable because
it assumes that the compiler stores the macro definition of FOO where
it is available to the interpreter:
(defmacro foo (x) `(car ,x))
(eval-when (eval compile load)
(print (foo '(a b c))))
A portable way to do the same thing would be to include the macro
definition inside the EVAL-WHEN:
(eval-when (eval compile load)
(defmacro foo (x) `(car ,x))
(print (foo '(a b c))))
Rationale:
The proposal generally reflects standard programming practices. The
primary purpose of the proposal is to make an explicit statement that
CL supports the behavior that most programmers expect and many
implementations already provide.
The primary point of controversy on this issue has been the treatment
of the initial value form by DEFCONSTANT, where there is considerable
variance between implementations. The effect of the current wording is
to legitimize all of the variants.
Current Practice:
Many (probably most) Common Lisp implementations, including VaxLisp
and Lucid Lisp, are already largely in conformance.
In VaxLisp, macro definitions that occur as a side effect of compiling
a DEFMACRO form are available to the compiler (even on subsequent
calls to COMPILE or COMPILE-FILE), but are not available to the
interpreter (even within the file being compiled).
By default, Kyoto Common Lisp evaluates *all* top level forms as they
are compiled, which is clearly in violation of the behavior specified
on p 69-70 of CLtL. There is a flag to disable the compile-time
evaluation, but then macros such as DEFMACRO, DEFVAR, etc. do not make
their definitions available at compile-time either.
Cost to implementors:
The intent of the proposal is specifically not to require the compiler
to have special knowledge about each of these macros. In
implementations whose compilers do not treat these macros as special
forms, it should be fairly straightforward to use EVAL-WHENs in their
expansions to obtain the desired compile-time side effects.
Cost to users:
Since CLtL does not specify whether and what compile-time side-effects
happen, any user code which relies on them is, strictly speaking,
nonportable. In practice, however, most programmers already expect
most of the behavior described in this proposal and will not find it
to be an incompatible change.
Benefits:
Adoption of the proposal will provide more definite guidelines on how
to write programs that will compile correctly under all CL
implementations.
Discussion:
Reaction to a preliminary version of this proposal on the common-lisp
mailing list was overwhelmingly positive. More than one person
responded with comments to the effect of "but doesn't CLtL already
*say* that somewhere?!?" Others have since expressed a more lukewarm
approval.
It has been suggested that this proposal should also include PROCLAIM.
However, since PROCLAIM is not a macro, its compile-time side effects
cannot be handled using the EVAL-WHEN mechanism. A separate proposal
seems more appropriate.
Item (3) allows for significant deviations between implementations.
While there is some sentiment to the effect that the compiler should
store definitions in a manner identical to that of the interpreter,
other people believe strongly that compiler side-effects should be
completely invisible to the interpreter. The author is of the opinion
that since this is a controversial issue, further attempts to restrict
this behavior should be considered as separate proposals.
It should be noted that user-written code-analysis programs must
generally treat these defining macros as special forms and perform
similar "compile-time" actions in order to correctly process
conforming programs.
-------
∂24-Jan-89 1255 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 24 Jan 89 12:55:07 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08355; 24 Jan 89 20:37 GMT
Date: Tue, 24 Jan 89 20:46:24 GMT
Message-Id: <17845.8901242046@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: David N Gray <Gray%dsg.csc.ti.com@NSS.Cs.Ucl.AC.UK>,
Cris Perdue <cperdue@sun.com>
Cc: sandra <@cs.utah.edu:sandra@defun>, cl-compiler@sail.stanford.edu
Regardless of the disposition of COMPILER-LET, I think the proposal had
better also say that *dump-circle* is rebound to its current value at least
during COMPILE-FILE. That way a source file can (eval-when (compile)
(setq *dump-circle* t)) if it contains circular structure.
*Dump-circle* is beginning to bother me. Because users can write
#n= and #n# in source code, they can specify constants that contain
sharing and circularities; and so those constants should be dumped.
I do not think it's reasonable to make the language weaker than the
source notation; and so I don't think *dump-circle* should exist
at all: it should always be as if it were true.
∂24-Jan-89 1300 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 24 Jan 89 12:58:09 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa08359; 24 Jan 89 20:39 GMT
Date: Tue, 24 Jan 89 20:48:20 GMT
Message-Id: <17852.8901242048@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: David N Gray <Gray%dsg.csc.ti.com@NSS.Cs.Ucl.AC.UK>,
sandra <@cs.utah.edu:sandra@defun>
In-Reply-To: David N Gray's message of Fri, 13 Jan 89 16:43:25 CST
Cc: Cris Perdue <cperdue@sun.com>, cl-compiler@sail.stanford.edu
> > Plus, what happens if you try to coalesce a constant in created one
> > place where *DUMP-CIRCLE* was true with one that was created in
> > another place where *DUMP-CIRCLE* was false?
>
> Assuming the compile-time evaluation happens in the first pass, then
> subsequent passes will see the flag as being either true or false for
> the entire file.
Seems a bit strange to me.
∂24-Jan-89 1313 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Jan 89 13:12:48 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA14070; Tue, 24 Jan 89 14:09:39 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA19747; Tue, 24 Jan 89 14:09:33 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901242109.AA19747@defun.utah.edu>
Date: Tue, 24 Jan 89 14:09:31 MST
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: David N Gray <Gray%dsg.csc.ti.com@NSS.Cs.Ucl.AC.UK>,
Cris Perdue <cperdue@sun.com>, sandra <sandra%defun@cs.utah.edu>,
cl-compiler@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Tue, 24 Jan 89 20:46:24 GMT
> I do not think it's reasonable to make the language weaker than the
> source notation; and so I don't think *dump-circle* should exist
> at all: it should always be as if it were true.
Well, by this reasoning, *print-circle* shouldn't exist either. I
take it you would like to see another proposal added that requires the
compiler to correctly handle circularity and sharing all the time?
-Sandra
-------
∂24-Jan-89 1330 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Jan 89 13:30:37 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 526080; Tue 24-Jan-89 16:28:22 EST
Date: Tue, 24 Jan 89 16:28 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: sandra%defun@cs.utah.edu
cc: CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: <8901242109.AA19747@defun.utah.edu>
Message-ID: <890124162830.7.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Tue, 24 Jan 89 14:09:31 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> I do not think it's reasonable to make the language weaker than the
> source notation; and so I don't think *dump-circle* should exist
> at all: it should always be as if it were true.
Well, by this reasoning, *print-circle* shouldn't exist either. I
take it you would like to see another proposal added that requires the
compiler to correctly handle circularity and sharing all the time?
I'm somewhat sympathetic to the symmetry rule you're trying to apply here,
but I think the situations are not completely analogous. In particular,
*PRINT-CIRCLE* can reliably be controlled at runtime in a way that does not
induce frustration and porting headaches. That means it is reasonable to allow
users to control the expense the printer goes to in cases where they know
they have something simple.
On the other hand, we've taken deliberate steps to see that users can't really
control all aspects of compilation that they might like to in order to
accomodate a wide variety of compilation models. Further, the output of
compilation is not trivially inspectable to determine if it is "good enough".
One might argue that *PRINT-CIRCLE* should be required to be defaultly T
and people should be permitted to set it to NIL in circumstances where they
want to `optimize' the output of an expression known to be safe. A similar
argument is hard to make for *DUMP-CIRCLE* because you can't set it to NIL
and be sure you are not screwing some compiler or user-defined macro which
had set it to T for some reason.
Bugs due to *PRINT-CIRCLE* being set wrong may be annoying, but they're easily
spotted and easily fixed. With COMPILE, the effects could be a lot more
mysterious -- I could easily imagine all day marathon debugging sessions that
eventually turn up a bug like this.
As such, I concur with Jeff that you really need to just require it to work.
For as much as that could be a headache for some implementors, the benefits
to users of being able to depend on such a thing would be quite measurable.
∂24-Jan-89 1335 CL-Compiler-mailer COMPILE-ENVIRONMENT-CONSISTENCY
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Jan 89 13:35:26 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 526084; Tue 24-Jan-89 16:32:18 EST
Date: Tue, 24 Jan 89 16:32 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: COMPILE-ENVIRONMENT-CONSISTENCY
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: <8901232221.AA19082@defun.utah.edu>
Message-ID: <19890124213250.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 23 Jan 89 15:21:32 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
issue COMPILE-ENVIRONMENT-CONSISTENCY was tabled because
some people at the meeting indicated they wanted to see some changes
to the writeup, and I need to know what those changes are.
My notes say just that increased precision is required and that
item 2h needs to be fixed for CLOS.
I hope to mail you the Symbolics comments on this and other compiler
issues today, or at worst tomorrow.
∂24-Jan-89 1415 Common-Lisp-Object-System-mailer DEFMETHOD compile-time processing
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 24 Jan 89 14:15:08 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA20353; Tue, 24 Jan 89 14:16:20 PST
Received: from lukasiewicz.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA14503; Tue, 24 Jan 89 14:12:36 PST
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA03288; Tue, 24 Jan 89 14:15:11 PST
Date: Tue, 24 Jan 89 14:15:11 PST
From: jrose@Sun.COM (John Rose)
Message-Id: <8901242215.AA03288@lukasiewicz.sun.com>
To: dussud@lucid.com
Cc: Gray@DSG.csc.ti.com, Common-Lisp-Object-System@SAIL.Stanford.edu,
CL-Compiler@SAIL.Stanford.edu
In-Reply-To: Patrick Dussud's message of Tue, 24 Jan 89 09:19:45 PST <8901241719.AA18054@challenger>
Subject: DEFMETHOD compile-time processing
Date: Tue, 24 Jan 89 09:19:45 PST
From: Patrick Dussud <dussud@lucid.com>
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 23 Jan 89 11:15:30 CST
From: David N Gray <Gray@DSG.csc.ti.com>
In the Meta Object Protocol draft number 10 [89-003], on page 3-16 it says
that
"At compile time: ... (5) The method function is computed by
evaluating the special form (FUNCTION <lambda>) in the lexical
environment of the DEFMETHOD. ... (7) The function ADD-METHOD is
called ..."
This isn't going to work. You can install the function at load
time in its lexical environment, or you can install it at compile time in
the null lexical environment, but you can't evaluate something at
compile-time in its run-time lexical environment.
you're right.
[A paraphase of your next paragraph: At compile time, a "remote
environment" data structure must be set up to model the eventual state
of the "local environment" which results from loading the compiled code.
A design goal of CLOS is to make these two kinds of environments as similar
as possible, having the same programmatic interface if possible. Yet, there
are objects which cannot be represented completely in a remote environment,
such as pieces of compiled code.]
...
Possible remedies include:
* Do the compile-time call to ADD-METHOD only if the DEFMETHOD appears at
top-level in a null lexical environment. This would be consistent with
the treatment of DEFMACRO in proposal DEFINING-MACROS-NON-TOP-LEVEL.
I don't consider this solution very satisfying, because it hides the problem.
It is possible to represent functions for the remote environment by normal
functions if the lexical environment is null, but still, they can't be
executed. The problem remains.
* Don't ever do a compile-time call to ADD-METHOD. I haven't seen a
reason why methods would need to be installed in the compile-time
environment. Apparently at least some information about generic
function definitions needs to be remembered for use when invoking
MAKE-METHOD-LAMBDA, but that wouldn't require being able to actually
call the generic function at compile-time.
This will lead to two different metaprogramming styles. Note that this is more
or less what Flavors does. It is workable, but not pretty. Maybe a better
solution is to standardize a representation for objects in the remote
environment, and have the compile-file time expansion create them. Add-method
and such work as before, function slots don't always contain real functions.
Patrick.
In Lisp, remote function objects are usually represented by their names.
For example, if we want at compile time to get hold of a function FOO to
insert it into code or data structure (in the course of macroexpansion,
say), we naturally don't attempt to grab hold of the function object
itself, or any compile-time representation of it; we use the name FOO
itself as a reference to the function. At compile time, the name may
not be defined, but we assume that it will be at load time. Lisp's
dynamic linking will ensure that we will access the code we want.
I'd like to present some generalizations of this which apply to CLOS.
Interestingly, Lisp already unifies the treatment of remote functions
(i.e., their names) and local ones (compiled code objects), in the
following way: All operations which work on compiled code objects also
work on their names __if__ those names are bound in the local
environment. For example, you can funcall or disassemble an FBOUNDP
symbol as easily as its binding, if it's bound. A remote reference
is coerced to a local one, for local operations.
This is a principle of unity which can address the problem at hand.
The proposals for non-symbolic function names (some of which are
motivated by CLOS work) generalize the set of names you can give to
functions. So, for example, if (SETF <name>) might be a valid function
name, so it can occur syntactically wherever a symbolic function name
might.
The semantics of non-symbolic function names (I contend) should tend to
preserve the unification between remote and local objects described
above. For example, a list like (SETF <name>) should support the
programmatic operations common to symbols and code objects:
DISASSEMBLE, SYMBOL-FUNCTION, FBOUNDP and (yes) FUNCALL.
Did you hear me suggest allowing FBOUNDP and FUNCALL on lists?
You did.
Consider this: Common Lisp already allows FUNCALL on lists, in what
turns out to be another case of remote-to-local coercion. If you
FUNCALL a list whose car is LAMBDA, the list is coerced to (or
interpreted as, which amounts to the same thing) the function it
specifies. In other word, the cons tree which names a function remotely
can serve as that function's. (By the way, an "anonymous" lambda is
really named by its cons tree.) The reference is validated late, at the
point of call: Just as symbols are checked for fboundp-ness, lambda
forms are walked by the interpreter when called, and not earlier.
Nevertheless, the reference, once validated, is equivalent to the
object itself.
Given function specifiers for method code, and given the unification
supplied by remote-to-local coercion of all function specifiers,
we can then store remote function specifiers in method objects,
to refer to code, and both local and remote operations will work
on them.
The paragraph David Gray mentioned above would then look something
like this:
At compile time: ... (5) The method function is set to the name of
the method, e.g., (METHOD <gfspec> <quals> <specs>). (This name may
or may not be FBOUNDP at compile time.) The form (DEFUN
<method-name> <args> <body>) is compiled in the lexical environment
of the DEFMETHOD. ... (7) The function ADD-METHOD is called ..."
... At load time, the DEFUN form for the method causes the method's
name to become bound to the specified code.
At both compile and load time, the method's function would be the name
of the actual function, which would be reliably FBOUNDP at load time.
Doing something like (FUNCALL (METHOD-FUNCTION M) X Y Z) would work
whenever reasonable, and cause an unbound function error at other times.
Note: As I've said before, nonsymbolic names can be useful for referring
to other things than functions. For example, mixture classes are
usefully named by cons trees of some sort. Consider extending the type
constructor AND to classes: (AND MY-VIEWPORT-CLASS BORDERS-MIXIN
CANVAS-STREAM-MIXIN). This could be implemented by extending
SYMBOL-CLASS to accept non-symbolic names, with a mixin manager which
builds and caches an otherwise-anonymous class for each mixture it sees.
Note also that a user-defined function specifier facility, with the
remote-to-local coercion rule, lets you build lambda-macros.
(Remember those?)
-- John
∂24-Jan-89 1746 CL-Compiler-mailer Re: DEFMETHOD compile-time processing
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Jan 89 17:46:47 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA21651; Tue, 24 Jan 89 18:43:37 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA20013; Tue, 24 Jan 89 18:43:23 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901250143.AA20013@defun.utah.edu>
Date: Tue, 24 Jan 89 18:43:21 MST
Subject: Re: DEFMETHOD compile-time processing
To: dussud@lucid.com
Cc: jrose@Sun.COM (John Rose), Gray@DSG.csc.ti.com,
Common-Lisp-Object-System@SAIL.Stanford.edu,
CL-Compiler@SAIL.Stanford.edu
In-Reply-To: jrose@Sun.COM (John Rose), Tue, 24 Jan 89 14:15:11 PST
> * Do the compile-time call to ADD-METHOD only if the DEFMETHOD appears at
> top-level in a null lexical environment. This would be consistent with
> the treatment of DEFMACRO in proposal DEFINING-MACROS-NON-TOP-LEVEL.
>
> I don't consider this solution very satisfying, because it hides the problem.
> It is possible to represent functions for the remote environment by normal
> functions if the lexical environment is null, but still, they can't be
> executed. The problem remains.
This may not be very satisfying, but it is probably the only practical
solution. We have already had a lot of debate on this regarding
DEFMACRO and the other defining macros. A number of people raised
very strong objections to things like DEFMACRO causing the definition
to appear in the compile-time environment when buried inside a control
construct such as IF, or inside a DEFUN. I don't see any reason why
those same arguments are not just as applicable to the CLOS defining
macros.
It seems exceedingly unlikely that we compiler people would be able to
agree on any major reversal of the current proposal on issue
DEFINING-MACROS-NON-TOP-LEVEL in the 6 weeks or so we have remaining.
It also seems unlikely that you CLOS people are going to have the time
to work out any alternative semantics before then. Even if we did
have more time to work out alternatives, to me it seems that
restricting the compile-time magic to top-level situations is the
simplest solution for all of us. I don't see that it would affect
other parts of CLOS, and it would just allow us to take the description
of the compile-time behavior of DEFMETHOD directly from the MOP
document.
Incidentally, I notice that the same considerations also affect
DEFCLASS and DEFGENERIC, both of which also want to create functional
objects. The MOP document doesn't seem to say anything about
DEFINE-METHOD-COMBINATION -- does anyone care to take a shot at
specifying its expansion? What does PCL do with it?
-Sandra
-------
∂24-Jan-89 1812 CL-Compiler-mailer Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Jan 89 18:12:05 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 526295; 24 Jan 89 21:10:04 EST
Date: Tue, 24 Jan 89 21:10 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
To: CL-Compiler@SAIL.STANFORD.EDU
cc: Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19890125021034.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
This is said to be a clarification, but I believe it is a change because
it makes the default semantics very different from the NOTINLINE
semantics (items 2b and 2c). However, I can't find anything in CLtL
that's contradicted by this proposal.
The second proposal paragraph says:
In all cases, however, compiling a program (with COMPILE or
COMPILE-FILE) provides a mechanism for forcing these transformations
to be applied and a guarantee that, once compiled, no further
transformations will be applied to that program.
What precisely is a "transformation"? I think this paragraph
doesn't mean anything and should be removed. If this means something
specific, for instance that MACROEXPAND can never be called as a
result of the evaluation of a top-level form in a COMPILE-FILE file,
nor as a result of calling a function defined in a COMPILE-FILE file,
it should say that explicitly. By the way I think that claim is
manifestly false, suppose you call MACROEXPAND explicitly, or call
something that calls it explicitly (for all I know a pretty printer
calls MACROEXPAND sometimes), or call a function defined in another
file that has an interpreted definition. Maybe you can define this
more precisely, but I don't immediately see how.
Someone else on the CLOS committee, other than me, will have to
take care of rewording item 2h.
Since the rest of the proposal is okay, I'd vote in favor anyway.
∂24-Jan-89 1826 CL-Compiler-mailer Issue: LOAD-TIME-EVAL (Version 8)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Jan 89 18:25:58 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 526302; 24 Jan 89 21:23:59 EST
Date: Tue, 24 Jan 89 21:24 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-TIME-EVAL (Version 8)
To: CL-Compiler@SAIL.STANFORD.EDU
cc: Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19890125022431.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
This issue passed, but I still have a couple of things to say about it.
It may be that it needs a follow-up to fix it up a little and resolve
some remaining semantic problems.
It is guaranteed that
the evaluation of <form> will take place only once when the file is
loaded, but the order of evaluation with respect to the "evaluation"
of top-level forms in the file is unspecified.
The second clause (order) is clearly wrong, since if a top-level form
contains a LOAD-TIME-EVAL, the load-time-eval must be evaluated no
later than when the evaluation of the top-level form reaches it. Also
I don't see how the first clause (once-only) can be guaranteed when
the LOAD-TIME-EVAL appears inside a top-level loop, unless it's
guaranteed that the compiler fully searches top-level forms to all
levels to find all possible LOAD-TIME-EVAL forms. Is it?
Implementations must guarantee that each reference to a
LOAD-TIME-VALUE expression results in at least one evaluation of its
nested <form>. For example,
(CONS #1=(LOAD-TIME-VALUE (COMPUTE-IT)) #1#)
must perform two calls to COMPUTE-IT; although there is only one
unique LOAD-TIME-VALUE expression, there are two distinct references
to it.
I think this is not well-defined. I don't have a written copy of your
amended version of this example, but I think it had the same problem.
Are the following examples one reference or two?
(CONS #1=(PROGN (LOAD-TIME-VALUE (COMPUTE-IT))) #1#)
(FLET ((F () (LOAD-TIME-VALUE (COMPUTE-IT)))) (F) (F))
(FLET ((F () (LOAD-TIME-VALUE (COMPUTE-IT))))
(DECLARE (INLINE F))
(F) (F))
(MACROLET ((F () `(LOAD-TIME-VALUE (COMPUTE-IT))))
(F) (F))
Similarly for "each call to EVAL must result in a new evaluation of <form>",
what things can LOAD-TIME-VALUE be nested inside and still be guaranteed
to cons fresh constants? What about displacing macros?
These examples show that you can't use EQ on the LOAD-TIME-VALUE expression
nor on any single thing containing it as your definition of expression
identity. In case you don't know what displacing macros are, they were
a Maclisp feature where the car and cdr of the macro call were replaced
by the car and cdr of the macro expansion, thus ensuring that the interpreter
only expanded a macro once. In general this is not a safe optimization in
a system with lexical scoping, since the same (EQ) macro call might be
inserted by macro expansion into several different lexical environments,
and the correct macro expansion of that call might vary depending on the
lexical environment. But it's still interesting as a way that the same
form can get into multiple places in a funny way.
If you didn't have the non-read-only case, then coalescing would be allowed
and you wouldn't have to try to define what a distinct reference to a
LOAD-TIME-VALUE expression is, since you wouldn't have to require that
each distinct reference gets evaluated. I guess too many people like
the non-read-only case for it to be likely to go away.
I have not been able to think of any satisfactory solution to this
problem, but I do not think you can get away with leaving it as-is. I
guess that the most likely route to a solution will involve defining
some sort of "tree walk" through the source code, defining the identity
of a form as the path taken through the tree to reach that form. I'm
guessing that the intuition that the proposal intended to capture is the
same thing that this tree walk does. This tree walk approach will run
into some significant difficulties with macros, but perhaps that's
tractable by defining it in terms of what EVAL does, somehow coping with
the multiple evaluations caused by looping and the missing evaluations
caused by conditionals.
Alternatively, you might abandon the intuition and think about the
consequences of just using EQ of the LOAD-TIME-VALUE expression. Would
it be so bad?
I don't understand why the read-only-p argument isn't evaluated in the
null lexical environment just like the form argument (instead of being
an unevaluated argument).
∂24-Jan-89 1830 CL-Compiler-mailer Issue: COMPILER-VERBOSITY (Version 5)
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 24 Jan 89 18:30:17 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 263343; Tue 24-Jan-89 21:28:12 EST
Date: Tue, 24 Jan 89 21:28 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COMPILER-VERBOSITY (Version 5)
To: CL-Compiler@SAIL.STANFORD.EDU
cc: Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19890125022847.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
I'm glad you decided to withdraw COMPILER-VERBOSITY:USE-CONDITIONS, I
thought it was excessive.
For LIKE-LOAD, I don't understand why there is a special variable to
control the default for one option (:VERBOSE), but not for the other
(:PRINT). That's just mindless inconsistency. The cost to users
section even remarks that some users will find it irritating that they
can't control the other default!
Let's just add variables *LOAD-PRINT* and *COMPILE-PRINT* controlling
the defaults for :PRINT options to both functions.
Note for current practice that Cloe has a *LOAD-PRINT* because we found
this was usually something you wanted to control per-user, not per-call.
∂24-Jan-89 1834 CL-Compiler-mailer Issue: CONSTANT-CIRCULAR-COMPILATION (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Jan 89 18:34:39 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 526307; Tue 24-Jan-89 21:32:30 EST
Date: Tue, 24 Jan 89 21:33 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: CONSTANT-CIRCULAR-COMPILATION (Version 5)
To: CL-Compiler@SAIL.STANFORD.EDU
cc: Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19890125023303.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
We haven't thought about this one real carefully, but here are some comments:
CONSTANT-CIRCULAR-COMPILATION:NO version 5 -- No, not acceptable not to preserve EQ
CONSTANT-CIRCULAR-COMPILATION:PRESERVE-SHARING-ONLY -- No, circularity should be allowed
CONSTANT-CIRCULAR-COMPILATION:FLAG -- No, this conflates sharing with circularity
Do not introduce a new word "DUMP" when we already have "COMPILE".
I would vote for one that always preserved EQ, and in addition had a
flag to control whether circularity was allowed.
There also should be a separate way to turn off EQness preservation for
individual types. At least, a customer asked for that once for conses,
to speed up writing of his large data structures that are known (or
assumed) not to contain any sharing of conses. Maybe the right way
to do this is a special variable whose value is a function of one
argument, called with an object appearing in a constant, returning T
if the compiler should try to preserve identity (under EQL) of that
object. Default always returns T. I don't care a lot about whether
you put this in.
∂24-Jan-89 1902 CL-Compiler-mailer Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Jan 89 19:02:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 526328; Tue 24-Jan-89 22:00:46 EST
Date: Tue, 24 Jan 89 22:01 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
To: CL-Compiler@SAIL.STANFORD.EDU
cc: Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19890125030118.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Good try but needs amendments.
I think this suffers from fundamental confusion between three distinct
concepts:
(1) relation of objects in the input of COMPILE-FILE to corresponding
objects in the result of LOAD of the output of COMPILE-FILE.
(2) relation of two objects in the output of a single COMPILE-FILE.
(3) relation of two objects in the output of two different COMPILE-FILEs.
All of these are important, but the answers are different. I think they
all have to be dealt with within one proposal, but the writeup for each
datatype should be conscious of each of the three issues.
I'm not going to try to evaluate the parenthesized remark about
cross-compilers under numbers and characters, other than to say that
this is a reflection of the same fundamental confusion. The test for
similarity as constants cannot ever really be EQL, since it is
impossible to bring the source and the product together into the same
Lisp to hand them as arguments to the same call to the EQL function.
You mean "something like EQL." I don't know a good way to say this
precisely, even though I think everyone knows what you mean. Or could
you define it in terms of loading the compiler's output file back into
the same Lisp it was compiled in? Does that work in all
implementations? It sure doesn't work in cross-compilers.
The part about uninterned symbols is inconsistent. Are they compared by
name, as it says in one place, or by EQ, as it says in another?
Also interned symbols accessible in the value of *PACKAGE* at compile
time should map into interned symbols accessible in the value of
*PACKAGE* at load time, rather than the stricter requirement that the
home package be the same. This allows some flexibility to deal with
minor redefinitions of packages. It's also current practice in any
implementation where the compiler/loader work like print/read and
only use a package prefix if the symbol is not accessible.
Arrays: saying that ARRAY-ELEMENT-TYPE has to be equal for arrays of all
ranks -except- 1 is crazy. As far as I can tell what you're trying to
accomplish is to make arrays of rank 1 (only) respect the fill-pointer.
That's fine, but except for the fill-pointer all ranks should be
consistent. ARRAY-ELEMENT-TYPE should have to be equal (actually,
EQUAL-TYPEP, a function missing from Common Lisp, which can be defined
in terms of two calls to SUBTYPEP in the obvious way).
Saying the compiler may not produce an adjustable array from a
non-adjustable array can be unimplementable for cross-compilers. I
think what you're actually trying to say is that if the input is of type
SIMPLE-ARRAY, the output must be, while at the same time it's valid for
the output to be of type SIMPLE-ARRAY even if the input is not. I agree
with it when it's said that way. I think if you simply say those words,
combined with listing the array attributes that are preserved, you'll
come out where you want to be.
I believe it's wrong for structures to be compared by component equality,
rather than by EQ. It is surely wrong for standard-class instances.
The LOAD-OBJECTS cleanup proposal can cover this for both structures
and standard-class instances; two of these are similar as constants
if they are EQ or if the MAKE-LOAD-FORMS method produces a form
that produces objects that are EQ. For generic functions and methods,
the comparison function is EQ and the reconstruction function is
defined by a MAKE-LOAD-FORMS method essentially coming from the
metaobject protocol.
Similarity for hash tables can just be EQUALP, now that JonL's amendment
to EQUAL-STRUCTURE has passed. No, that's wrong, it uses the wrong
function to compare the values. But you can make a reference to EQUALP
to help explain the algorithm.
Readtables probably can't work since most functions aren't allowed, and
readtables contain functions.
Everything this says about functions strikes me as confused, but I
haven't thought about it very hard.
I'd look to look at this whole proposal again harder when you have
a revised version.
Symbolics Genera current practice: aside from some current bugs we
have with circular structures of certain types and with preserving
the identity of CONSes under EQ, this is more or less consistent
with our current practice, if you made the changes implied by my
earlier comments. We preserve the :displaced-to and :fill-pointer
array attributes. I doubt that we do what the proposal says for
hash-tables, readtables, and random-states. We support dumping
compiled and interpreted functions, but not closures, which in
effect means we don't support dumping functions.
∂24-Jan-89 1912 CL-Compiler-mailer Issue: QUOTE-MAY-COPY (Version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Jan 89 19:12:28 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 526332; Tue 24-Jan-89 22:10:28 EST
Date: Tue, 24 Jan 89 22:10 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: QUOTE-MAY-COPY (Version 4)
To: CL-Compiler@SAIL.STANFORD.EDU
cc: Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19890125031059.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
You said you were going to completely rewrite this issue, so these
comments may be useless. On the other hand, I may as well send them
on the off-chance that they might assist with the rewrite.
QUOTE-MAY-COPY:ALWAYS version 4 -- No
QUOTE-MAY-COPY:NOT-EVAL-OR-COMPILE -- Yes
QUOTE-MAY-COPY:NOT-EVAL -- No
Note that I have changed my position on this (formerly was ALWAYS). I
might change back though. Kent likes NOT-EVAL-OR-COMPILE or a
restricted version of ALWAYS that doesn't limit what can be used as a
constant except in COMPILE-FILE. If I switch to ALWAYS I would agree
with Kent's amendment that all objects are allowed as constants and
copying is permitted only for the objects where equivalence is defined.
Symbolics Genera current practice is that COMPILE copies list, string,
(non-structure, non-displaced) array, and (I-Machine only) closure
constants. However, I think this is wrong. Everything within a single
Lisp world should remain EQL. COMPILE-FILE obviously can't make things
in the output be EQL to things in the input, but it can preserve the
relationship that if x and y are EQL in the input, then compile(x) and
compile(y) are EQL in the output. In addition, coalescing of equivalent
constants should be allowed so that x and y not EQL does not imply
compile(x) and compile(y) not EQL. When not using COMPILE-FILE, the
rule should be that EQL is preserved and copying is allowed only if
the compiler can somehow prove that no other references to the object
exist. At least for Symbolics this means that using COMPILE-FILE
can give more efficient (in terms of virtual memory locality) code
than you can get with COMPILE. I don't know Symbolics Cloe current
practice and forgot to find out.
I oppose anything that makes EVAL and COMPILE different from each other.
Is the output of LOAD-TIME-EVAL supposed to be subject to copying or not?
Answer explicitly in the proposal so no one can stay confused.
There is a claim that QUOTE-MAY-COPY:NOT-EVAL-OR-COMPILE would require
major revamping of some implementations (PSL/PCLS and maybe KCL). I
find this hard to believe, but if it's true I might change my vote
to ALWAYS on the grounds of that. I'd have to hear more about the
specific implementation problems first. It seems to me that constant
copying in COMPILE can only be a matter of efficiency, and compiled
functions always have to have access to normal Lisp objects.
Note that it isn't safe, I contend, to copy constants in COMPILE-FILE if
the constant object is referenced from elsewhere in the file. EQL needs
to be preserved within one file. I think I see how to implement this
correctly but it will take some work (in Symbolics Genera).
Nonetheless, it's right. Fundamentally the issue is whether we care
more about doing what's best or about the cost for implementors. I
don't think there is any significant cost to users on any of these.
Note that on compatibility issues I care very strongly about cost to
users, but I don't care hardly at all about cost to implementors.
Implementors are tough and they can take it, or they wouldn't still be
in business.
∂24-Jan-89 1914 CL-Compiler-mailer Issues: DEFINING-MACROS-NON-TOP-LEVEL, EVAL-WHEN-NON-TOP-LEVEL, COMPILED-FUNCTION-REQUIREMENTS
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Jan 89 19:14:40 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 526334; Tue 24-Jan-89 22:12:44 EST
Date: Tue, 24 Jan 89 22:13 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issues: DEFINING-MACROS-NON-TOP-LEVEL, EVAL-WHEN-NON-TOP-LEVEL, COMPILED-FUNCTION-REQUIREMENTS
To: CL-Compiler@SAIL.STANFORD.EDU
cc: Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19890125031316.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
We have a lot to say on these three topics but I've run out of time. I'm
just sending this note so you know to expect something on these three,
most likely on Wednesday or Thursday of this week.
∂24-Jan-89 1940 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Jan 89 19:39:56 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA23249; Tue, 24 Jan 89 20:38:29 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA20098; Tue, 24 Jan 89 20:38:15 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901250338.AA20098@defun.utah.edu>
Date: Tue, 24 Jan 89 20:38:14 MST
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 24 Jan 89 21:24 EST
> Date: Tue, 24 Jan 89 21:24 EST
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> The second clause (order) is clearly wrong, since if a top-level form
> contains a LOAD-TIME-EVAL, the load-time-eval must be evaluated no
> later than when the evaluation of the top-level form reaches it.
Yes, you're right here.
> If you didn't have the non-read-only case, then coalescing would be allowed
> and you wouldn't have to try to define what a distinct reference to a
> LOAD-TIME-VALUE expression is, since you wouldn't have to require that
> each distinct reference gets evaluated. I guess too many people like
> the non-read-only case for it to be likely to go away.
We talked about removing the non-read-only case before and for the
same reasons, but Pitman objected, saying he thought it was essential
to the proposal. Basically, if you're going to do destructive
operations on an object, bad things will happen if it's shared with
anything else. I suppose an alternative would be to shift this burden
onto programmers rather than implementors, as long as implementors are
not permitted to coalesce EQUAL LOAD-TIME-VALUE expressions (which
would result in unexpected sharing).
> I have not been able to think of any satisfactory solution to this
> problem, but I do not think you can get away with leaving it as-is. I
> guess that the most likely route to a solution will involve defining
> some sort of "tree walk" through the source code, defining the identity
> of a form as the path taken through the tree to reach that form. I'm
> guessing that the intuition that the proposal intended to capture is the
> same thing that this tree walk does.
Yes, that is pretty much what I had in mind, but I agree it is not
formally stated. Perhaps a more formal statement would be that you do
a code walk to expand all macros, then do a COPY-TREE on the resulting
code, then all the LOAD-TIME-VALUE expressions you end up with would have
the right uniqueness properties.
> Alternatively, you might abandon the intuition and think about the
> consequences of just using EQ of the LOAD-TIME-VALUE expression. Would
> it be so bad?
That's pretty much the alternative I mentioned above, I guess. Maybe
you could try to resolve this with Pitman off-line, since he was the
one who was really pushing for allowing destructive operations, which
are really the source of the problem. I wouldn't have any objection
to seeing whatever you two agree on submitted as a cleanup to the
cleanup.
-Sandra
-------
∂24-Jan-89 1947 CL-Compiler-mailer Re: Issue: COMPILER-VERBOSITY (Version 5)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Jan 89 19:47:52 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA23385; Tue, 24 Jan 89 20:46:18 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA20112; Tue, 24 Jan 89 20:46:14 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901250346.AA20112@defun.utah.edu>
Date: Tue, 24 Jan 89 20:46:13 MST
Subject: Re: Issue: COMPILER-VERBOSITY (Version 5)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 24 Jan 89 21:28 EST
Yes, adding *LOAD-PRINT* and *COMPILE-PRINT* to the LIKE-LOAD proposal
sounds reasonable. I was originally a bit hesitant to change LOAD at
all, thinking it would open the door for all sorts of incompatible
changes, but there seems to be some justification for this one.
-Sandra
-------
∂24-Jan-89 2049 CL-Compiler-mailer Re: Issue: QUOTE-MAY-COPY (Version 4)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Jan 89 20:49:11 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA24458; Tue, 24 Jan 89 21:47:42 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA20141; Tue, 24 Jan 89 21:47:25 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901250447.AA20141@defun.utah.edu>
Date: Tue, 24 Jan 89 21:47:24 MST
Subject: Re: Issue: QUOTE-MAY-COPY (Version 4)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 24 Jan 89 22:10 EST
> If I switch to ALWAYS I would agree
> with Kent's amendment that all objects are allowed as constants and
> copying is permitted only for the objects where equivalence is defined.
I sent around a draft of the new writeup to cl-compiler the other day
that includes a proposal along these lines. Proposal
QUOTE-MAY-COPY:NOT-EVAL seems to be uniformly hated by everyone, so I
let it drop.
> There is a claim that QUOTE-MAY-COPY:NOT-EVAL-OR-COMPILE would require
> major revamping of some implementations (PSL/PCLS and maybe KCL). I
> find this hard to believe, but if it's true I might change my vote
> to ALWAYS on the grounds of that. I'd have to hear more about the
> specific implementation problems first. It seems to me that constant
> copying in COMPILE can only be a matter of efficiency, and compiled
> functions always have to have access to normal Lisp objects.
For KCL, my understanding of what happens is that COMPILE ends up PRINTing
the constants to a file and then reading it in again. Jeff Dalton claims
that COMPILE could be fixed to work around this problem, though.
For PSL/PCLS, compiled code objects are copied into a part of memory
that is not scanned by the garbage collector. Constant references are
just anonymous pointers sitting at unknown locations within the code.
Because of this, compiled code can't contain any references to
constants that might possibly be relocated, so all constants have to
be copied into read-only memory when the functions that reference them
are compiled. There are workarounds involving indirecting through a
table, or maintaining a table of offsets of constant pointers within
each function, but it seems unlikely that anybody will have the
ambition to implement them, at this point. We've never claimed that
PSL/PCLS was a real Common Lisp anyway.
I'm not sure what Utah Common Lisp was planning to do about COMPILE;
as far as I know, the compiler is strictly a cross-compiler now. I
heard a lot of unhappy noises from the main compiler hacker though,
the last time I talked to him about this. A-Lisp (the implementation
I was working on personally) treats code objects the same way PSL/PCLS
does, but it doesn't have COMPILE implemented yet either (and probably
never will). Both UCL and A-Lisp refuse to compile circular
constants, because the loader wants to build constants bottom-up in
both implementations; UCL gets stuck in an infinite loop and A-Lisp
signals an error.
There might be some other implementations that would be affected that
I don't know about. I think I remember Walter saying that VaxLisp
also copied constants and didn't GC code, but I might be mistaken.
-Sandra
-------
∂25-Jan-89 0523 CL-Compiler-mailer Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 25 Jan 89 05:15:21 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00902g; Wed, 25 Jan 89 05:07:45 PST
Received: by bhopal id AA08200g; Wed, 25 Jan 89 05:10:06 PST
Date: Wed, 25 Jan 89 05:10:06 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901251310.AA08200@bhopal>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: David A. Moon's message of Tue, 24 Jan 89 22:10 EST <19890125031059.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
re: I oppose anything that makes EVAL and COMPILE different from each other.
Suppose an implementation has an EVAL which doesn't _guarantee_ that
any two successive calls on a function similar to:
(DEFUN FOO () (QUOTE <frob>))
will return EQ things [unless, of course, the equivalence class of
coalescings of <frob> has only one element in it; this is true of
symbols and most implementations of fixnums]. In that implementation,
COMPILE should be permitted to "copy" constants, right? [Please be
aware that I'm not suggesting this as a good idea -- but some have
noted that unless you require a "prepass" type evaluator, it may
be impossible to preclude macro-expansions from being done repeatedly
and thus returning non-EQ values on each call to some function].
Put another way, no one has ever proposed to "make EVAL and COMPILE
[be] different". Rather, the proposal is to be explicitly vague
about guarantees of EQness of constants for portable code.
Although the call has long been sounded, no one yet has offered
realistic applications where coalescing of constants -- either by
COMPILE or COMPILE-FILE -- would hinder either the application or
the coding thereof. The only comments have been micro-examples made
with malice-aforethought to demonstrate that in some circumstance is
it *possible* to determine whether or not non-trivial coalescing has
occurred.
As it stands now, I would oppose any effort to limit the flexibility
of implementors on this issue without good cause.
Since we have already passed the proposal that permits constants to
be "read-only" -- it is an error to modify them -- and have already
passed the proposal that allows access to updateable structures --
LOAD-TIME-EVAL -- then there is no excuse for being overly concerned
with the storage address of quoted data. People who have mistakenly
used structured constants as updatable data should convert over to
either LOAD-TIME-EVAL or DEFPARAMETER.
Some have suggested that quoted non-symbols might be good for use
as unique markers. This does not accord with what I have seen in
very extensive use. By far, the majority of cases I've seen use
keywords (a classic use!); those that don't, seem generally to have
had the good sense to use devar or defparameter (which in fact is
how some implementations achive EQLness in support for DEFCONSTANT).
However the final killer, I believe, in this scenario, is not EVAL
followed by COMPILE, but rather EVAL followed by reading in a new
definition followed by EVAL. Even though QUOTE didn't copy anything,
and even though EVAL didn't copy anything, the output of the newly
defined constant-returning fuction is no longer EQL to what it was
before. And we do want to facilitate redefining functions on
the fly, don't we?
-- JonL --
∂25-Jan-89 0744 CL-Compiler-mailer Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 25 Jan 89 07:44:20 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa08427; 25 Jan 89 9:57 EST
Received: from draper.com by RELAY.CS.NET id ah00407; 25 Jan 89 9:55 EST
Date: Wed, 25 Jan 89 08:07 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Re: Issues DECLARATION-SCOPE and DEFINING-MACROS-NON-TOP-LEVEL
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER,SEB1525
>>
>> If you don't make it a special form, then MACROEXPAND can change its semantics.
>> [eg, if LOCALLY expands into LET, but LET is not something that works at toplevel.]
>> Currently, I don't think that's permitted -- MACROEXPAND is normally a
>> semantics-preserving operation. I think Moon is right that adding LOCALLY to
>> that list would seem to require that it be implemented as a special form.
>
>An alternative would be to say that LET passes through "top-level-ness" when
>its binding list is NIL.
>
Oh boy. So we want to make EVAL-WHEN *not* pass through top-level-ness, but we
*do* want to make LET pass it through. Please. "LET"'s not go in two
diametrically opposite directions. Either we should take a "lean and mean"
approach to top-level-ness (which includes purging the language of most of its
strange behavior wrt top-level-ness), or we should make it more permissive,
but for god's sake be consistent.
∂25-Jan-89 0818 CL-Compiler-mailer Re: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 25 Jan 89 08:18:35 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA05058; Wed, 25 Jan 89 09:17:02 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA20436; Wed, 25 Jan 89 09:16:51 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901251616.AA20436@defun.utah.edu>
Date: Wed, 25 Jan 89 09:16:50 MST
Subject: Re: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 24 Jan 89 21:10 EST
> Date: Tue, 24 Jan 89 21:10 EST
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> This is said to be a clarification, but I believe it is a change because
> it makes the default semantics very different from the NOTINLINE
> semantics (items 2b and 2c). However, I can't find anything in CLtL
> that's contradicted by this proposal.
I suppose the most consistent specification would be to only allow
tail recursion optimization in the -presence- of an INLINE
declaration. But I think the current wording of item 2b more closely
represents current practice. It's how A-Lisp and Utah Common Lisp
work, and I think VaxLisp does this also. The rather ancient version
of Lucid Lisp I have seems to do tail recursion optimization even if
you proclaim the function NOTINLINE. Is there some other particular
behavior you'd like to see specified instead?
Item 2c (block compilation) has been more controversial -- KCL does
this, but many people seem to think that this should not be the
default behavior of the compiler. My plan for voting on this issue at
the last meeting was to first ask for a vote on an amendment to remove
this particular item, but it never got that far. I suppose that if
nobody speaks up for it in the meantime, we could just go ahead and
remove it from the next version.
> The second proposal paragraph says: [...]
>
> What precisely is a "transformation"? I think this paragraph
> doesn't mean anything and should be removed.
We have another issue, COMPILED-FUNCTION-REQUIREMENTS, that deals with
this in more detail, so removing the paragraph here would be OK with
me.
-Sandra
-------
∂25-Jan-89 0840 CL-Compiler-mailer DEFMETHOD compile-time processing
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 25 Jan 89 08:40:16 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA02375g; Wed, 25 Jan 89 08:35:13 PST
Received: by challenger id AA19066g; Wed, 25 Jan 89 08:31:05 PST
Date: Wed, 25 Jan 89 08:31:05 PST
From: Patrick Dussud <dussud@lucid.com>
Message-Id: <8901251631.AA19066@challenger>
To: sandra%defun@cs.utah.edu
Cc: Common-Lisp-Object-System@SAIL.Stanford.edu, CL-Compiler@SAIL.Stanford.edu
In-Reply-To: Sandra J Loosemore's message of Tue, 24 Jan 89 18:43:21 MST <8901250143.AA20013@defun.utah.edu>
Subject: DEFMETHOD compile-time processing
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Date: Tue, 24 Jan 89 18:43:21 MST
> * Do the compile-time call to ADD-METHOD only if the DEFMETHOD appears at
> top-level in a null lexical environment. This would be consistent with
> the treatment of DEFMACRO in proposal DEFINING-MACROS-NON-TOP-LEVEL.
>
> I don't consider this solution very satisfying, because it hides the problem.
> It is possible to represent functions for the remote environment by normal
> functions if the lexical environment is null, but still, they can't be
> executed. The problem remains.
This may not be very satisfying, but it is probably the only practical
solution. We have already had a lot of debate on this regarding
DEFMACRO and the other defining macros. A number of people raised
very strong objections to things like DEFMACRO causing the definition
to appear in the compile-time environment when buried inside a control
construct such as IF, or inside a DEFUN. I don't see any reason why
those same arguments are not just as applicable to the CLOS defining
macros.
It seems exceedingly unlikely that we compiler people would be able to
agree on any major reversal of the current proposal on issue
DEFINING-MACROS-NON-TOP-LEVEL in the 6 weeks or so we have remaining.
It also seems unlikely that you CLOS people are going to have the time
to work out any alternative semantics before then. Even if we did
have more time to work out alternatives, to me it seems that
restricting the compile-time magic to top-level situations is the
simplest solution for all of us. I don't see that it would affect
other parts of CLOS, and it would just allow us to take the description
of the compile-time behavior of DEFMETHOD directly from the MOP
document.
Even if we decide to take this stand, the problem won't be entirely solved.
Metaprogrammers won't be able to blindly get their paws on a method object,
and do something that will cause the method-function to be called. If the
method-function is a remote environment function, it may not be able to run in
the local environment. I consider the semantics of the macros and the
representation of remote environment objects being two distincts issues. My
objections were not directed at the semantics issue, but at the representation
issue. I expect that other CLOS members will give opinions on the semantics
issue.
Incidentally, I notice that the same considerations also affect
DEFCLASS and DEFGENERIC, both of which also want to create functional
objects. The MOP document doesn't seem to say anything about
DEFINE-METHOD-COMBINATION -- does anyone care to take a shot at
specifying its expansion? What does PCL do with it?
That's right, all those macros create functional object, therefore are subject
to the ruling concerning macros in non null lexical environment.
Patrick.
∂25-Jan-89 0900 CL-Compiler-mailer Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 25 Jan 89 09:00:36 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06203; Wed, 25 Jan 89 09:58:58 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA20469; Wed, 25 Jan 89 09:58:53 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901251658.AA20469@defun.utah.edu>
Date: Wed, 25 Jan 89 09:58:52 MST
Subject: Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 24 Jan 89 22:01 EST
> The part about uninterned symbols is inconsistent. Are they compared by
> name, as it says in one place, or by EQ, as it says in another?
I don't see the inconsistency. If two symbols in a single Common Lisp
"address space" have the same name and are interned in the same home
package, they *must* be EQ, right?
> Also interned symbols accessible in the value of *PACKAGE* at compile
> time should map into interned symbols accessible in the value of
> *PACKAGE* at load time, rather than the stricter requirement that the
> home package be the same. This allows some flexibility to deal with
> minor redefinitions of packages. It's also current practice in any
> implementation where the compiler/loader work like print/read and
> only use a package prefix if the symbol is not accessible.
This could cause some interesting problems if the value of *PACKAGE*
changes throughout the file. Note that neither CLtL nor my revised
proposal on issue IN-PACKAGE-FUNCTIONALITY forbid this from happening.
(CLtL merely -suggests- putting the call to IN-PACKAGE at the top of
the file, "as a matter of style"). Suppose that at compile-time,
symbol BAR is accessible in both packages P1 and P2 (but its home
package is somewhere else), and at load-time it's not.
(in-package :p1)
... 'bar ...
(in-package :p2)
... 'bar ...
Would the correct load-time behavior for this example be to create two
different, non-EQ symbols named BAR, one in each of packages P1 and
P2? That would violate the principle that symbols within a single
file that are EQ at compile time must also be EQ at load time. My own
feeling is that no valid program ought to have the package environment
defined inconsistently between compile and load time in this manner,
and we shouldn't waste our time trying to specify what happens if it
is.
> Arrays: saying that ARRAY-ELEMENT-TYPE has to be equal for arrays of all
> ranks -except- 1 is crazy.
You're right, this was probably an oversight.
> I believe it's wrong for structures to be compared by component equality,
> rather than by EQ. It is surely wrong for standard-class instances.
> The LOAD-OBJECTS cleanup proposal can cover this for both structures
> and standard-class instances; two of these are similar as constants
> if they are EQ or if the MAKE-LOAD-FORMS method produces a form
> that produces objects that are EQ. For generic functions and methods,
> the comparison function is EQ and the reconstruction function is
> defined by a MAKE-LOAD-FORMS method essentially coming from the
> metaobject protocol.
I disagree with the idea of changing the handling for structures.
Introducing the LOAD-OBJECTS protocol for standard-class instances is fine,
but structures have been part of the language for a while already and I
don't see any need to change their handling in an incompatible way. If
people find that the default handling of structures is not sufficient for
their needs, that's probably a sign that they really need to use the more
complex protocol for standard-class objects instead.
> Everything this says about functions strikes me as confused, but I
> haven't thought about it very hard.
It strikes me as confused, too. I've been arguing for simply not requiring
functions to be dumpable at all, but not everybody agrees with me.
-Sandra
-------
∂25-Jan-89 0913 CL-Compiler-mailer Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Jan 89 09:13:16 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 526640; Wed 25-Jan-89 12:11:14 EST
Date: Wed, 25 Jan 89 12:11 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
To: jonl@lucid.com
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8901251310.AA08200@bhopal>
Message-ID: <890125121120.8.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Wed, 25 Jan 89 05:10:06 PST
From: Jon L White <jonl@lucid.com>
re: I oppose anything that makes EVAL and COMPILE different from each other.
Suppose an implementation has an EVAL which doesn't _guarantee_ that
any two successive calls on a function similar to:
(DEFUN FOO () (QUOTE <frob>))
will return EQ things [unless, of course, the equivalence class of
coalescings of <frob> has only one element in it; this is true of
symbols and most implementations of fixnums]. ...
I found it somewhat difficult to understand this message because Moon
spoke about EQL and you replied about EQ. It took me a while to assure
myself that this discrepancy wasn't relevant to your argument. Let's just
all refer to EQL from now on if at all possible.
...
Although the call has long been sounded, no one yet has offered
realistic applications where coalescing of constants -- either by
COMPILE or COMPILE-FILE -- would hinder either the application or
the coding thereof.
Well, yes, they have:
1. The case of #, is one. I have always assumed that #, was capable of
delivering up a value which could be depended upon not to change.
Now that there's LOAD-TIME-VALUE, presumably you mean to exempt
this case.
2. The case of circular structure is another.
'#1=(A . #1#)
If permitting copying implies that the copier might blow out, then
I it means that writing (DEFUN FOO () '#1=(A . #1#)) is not useful
because I must always assume that some implementation somewhere might
blow out. On the other hand, I've suggested a restriction on copying
that would obviate this concern, too. Perhaps you're presupposing it
as well.
The problem is that a lot of copying advocates have been going around
trying to use "the need for copying" as leverage for restricting
the set of things which I may quote. My view is that it is my write
to quote whatever I want, and it's up to the person who thinks they
can do something fun with copying to not get themselves in deeper than
they can handle.
If both of these issues is taken as exempted from your discussion, then
I concur. But in previous discussions neither of these have been taken
as given, and certainly for me these issues are -very- real.
The only comments have been micro-examples made
with malice-aforethought to demonstrate that in some circumstance is
it *possible* to determine whether or not non-trivial coalescing has
occurred.
See above.
As it stands now, I would oppose any effort to limit the flexibility
of implementors on this issue without good cause.
See above.
Since we have already passed the proposal that permits constants to
be "read-only" -- it is an error to modify them --
Right.
Objection 1 above addresses the question of whether #, things are part of
the quoted structure and hence not covered. By making LOAD-TIME-VALUE a
special form that doesn't live in QUOTE, we gloss that issue entirely.
On the other hand, objection 2 above addresses a problem which does not
arise due to trying to modify anything. It is at the heart of why this
issue matters at all to me.
and have already passed the proposal that allows access to updateable
structures -- LOAD-TIME-EVAL -- then there is no excuse for being
overly concerned with the storage address of quoted data.
Right. Previous discussions have not been able to assume the existence
of this.
People who have mistakenly used structured constants as updatable
data should convert over to either LOAD-TIME-EVAL or DEFPARAMETER.
Right. But that doesn't address objection 2.
Some have suggested that quoted non-symbols might be good for use
as unique markers.
Right. I always use (LIST NIL), not '(NIL) myself.
This does not accord with what I have seen in
very extensive use. By far, the majority of cases I've seen use
keywords (a classic use!); those that don't, seem generally to have
had the good sense to use devar or defparameter (which in fact is
how some implementations achive EQLness in support for DEFCONSTANT).
Right.
However the final killer, I believe, in this scenario, is not EVAL
followed by COMPILE, but rather EVAL followed by reading in a new
definition followed by EVAL.
This is a very good example because it highlights some interesting issues.
However, note that my objection 2 still applies because that problemsome
situation [the circularity or whatever] will be correctly reproduced by
this action.
[As a sidelight, note that all my uses of #, were insensitive to this
because my most common use of #, was something like
#,(OR (GETHASH 'symbol table) (SETF (GETHASH 'symbol table) (compute)))
Since the first read would create the hash table entry and the second
read would re-access the table, my uses of #, were not affected by this
test. This is a non-issue now that there's LOAD-TIME-VALUE, but was
a commonly overlooked issue prior: multiple evaluation didn't have to
mean a new frob was consed.]
Even though QUOTE didn't copy anything, and even though EVAL didn't
copy anything, the output of the newly defined constant-returning
fuction is no longer EQL to what it was before. And we do want to
facilitate redefining functions on the fly, don't we?
I think these points are well-taken. As long as my objection 2 above is
dealt with, I'm happy with this line of reasoning.
∂25-Jan-89 0959 CL-Compiler-mailer Re: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 25 Jan 89 09:58:55 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA08191; Wed, 25 Jan 89 10:00:06 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA14082; Wed, 25 Jan 89 09:56:45 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA24301; Wed, 25 Jan 89 09:57:54 PST
Date: Wed, 25 Jan 89 09:57:54 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901251757.AA24301@clam.sun.com>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, jonl@lucid.com
Subject: Re: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
Cc: CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
> Suppose an implementation has an EVAL which doesn't _guarantee_ that
> any two successive calls on a function similar to:
>
> (DEFUN FOO () (QUOTE <frob>))
>
> will return EQ things [unless, of course, the equivalence class of
> coalescings of <frob> has only one element in it; this is true of
> symbols and most implementations of fixnums]. In that implementation,
> COMPILE should be permitted to "copy" constants, right?
Let us hope there are no such implementations. I do not buy the
subsequent argument that some implementations need to be this way.
In fact, let us rule out such implementations.
I'm not sure how the following is intended to relate, but let
me reiterate a point I have made before, in case it isn't already
110% clear:
> However the final killer, I believe, in this scenario, is not EVAL
> followed by COMPILE, but rather EVAL followed by reading in a new
> definition followed by EVAL. Even though QUOTE didn't copy anything,
> and even though EVAL didn't copy anything, the output of the newly
> defined constant-returning fuction is no longer EQL to what it was
> before. And we do want to facilitate redefining functions on
> the fly, don't we?
(None of the following contradicts JonL's paragraph just above.) Note the
invocation of READ in this scenario. READ performed twice, LOAD
performed twice, PRINT followed by READ, PRINT followed by COMPILE-FILE
followed by LOAD, etc., all have effects *similar to* copying of Lisp
objects. To be more precise, they each result in certain objects being
equivalent (EQUAL or similar as constants), but not EQ.
We must all realize that this phenomenon is separate from any
possible copying done by QUOTE.
As JonL has mentioned, we may also wish to allow a copy of some
sort to be made between the time a list structure is made into
a function and the time of completion of the first evaluation
of a (quoted or self-evaluating) constant in a function. That
would not affect this scenario.
∂25-Jan-89 1137 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 25 Jan 89 11:37:01 PST
Received: by ti.com id AA08156; Wed, 25 Jan 89 13:35:03 CST
Received: from Kelvin by tilde id AA16666; Wed, 25 Jan 89 13:27:12 CST
Message-Id: <2810748378-9770893@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 25 Jan 89 13:26:18 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>,
CL-Compiler@SAIL.STANFORD.EDU
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
In-Reply-To: Msg of Tue, 24 Jan 89 20:38:14 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> > guess that the most likely route to a solution will involve defining
> > some sort of "tree walk" through the source code, defining the identity
> > of a form as the path taken through the tree to reach that form. I'm
> > guessing that the intuition that the proposal intended to capture is the
> > same thing that this tree walk does.
>
> Yes, that is pretty much what I had in mind, but I agree it is not
> formally stated. Perhaps a more formal statement would be that you do
> a code walk to expand all macros, then do a COPY-TREE on the resulting
> code, then all the LOAD-TIME-VALUE expressions you end up with would have
> the right uniqueness properties.
In other words, the interpreter would be required to do a pre-pass over the
code. In discussions in other contexts, it seemed that the consensus was
that we did not want to require a pre-pass implementation approach or to rule
out a displacing macros approach. I don't think we want to reverse that
position just to satisfy the fine print in this one feature.
> > Alternatively, you might abandon the intuition and think about the
> > consequences of just using EQ of the LOAD-TIME-VALUE expression. Would
> > it be so bad?
>
> That's pretty much the alternative I mentioned above, I guess.
This looks like the only viable answer to me.
∂25-Jan-89 1247 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Jan 89 12:47:33 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 526831; Wed 25-Jan-89 15:45:06 EST
Date: Wed, 25 Jan 89 15:45 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: Gray@DSG.csc.ti.com
cc: sandra%defun@cs.utah.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <2810748378-9770893@Kelvin>
Message-ID: <890125154510.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Wed, 25 Jan 89 13:26:18 CST
From: David N Gray <Gray@DSG.csc.ti.com>
...
> > Alternatively, you might abandon the intuition and think about the
> > consequences of just using EQ of the LOAD-TIME-VALUE expression. Would
> > it be so bad?
>
> That's pretty much the alternative I mentioned above, I guess.
This looks like the only viable answer to me.
I can't parse the original sentence [by Moon?] above, so I can't know whether
to agree or disagree. Which intuition are we talking about abandoning:
Intuition #1: (DOTIMES (I 5) (PRINT (LOAD-TIME-VALUE (F))))
evaluates the LOAD-TIME-VALUE expression only once.
Intuition #2: (DOTIMES (I 5) (PRINT (EVAL '(LOAD-TIME-VALUE (F)))))
evaluates the LOAD-TIME-VALUE expression at least 5 times.
I'm reluctant to abandon intuition #2 because I fear that it will complicate
debugging tremendously. eg, if the dynamic state changes [eg, due to a bug
fix] such that (F) can return a new value but it keeps returning an old value
due to some hidden cache, I think the effects would be very frustrating.
I'm willing to relax intuition #1 because I can see that some interpreters
would have too hard a time dealing with it. Nevertheless, I'd like to have
an implementation hint suggesting that the intuition be supported where
feasible.
Given that intuition #1 is relaxed, I don't see the difficulty in supporting
intuition #2.
∂25-Jan-89 1404 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 25 Jan 89 14:03:57 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA17953; Wed, 25 Jan 89 14:54:00 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA20726; Wed, 25 Jan 89 14:52:57 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901252152.AA20726@defun.utah.edu>
Date: Wed, 25 Jan 89 14:52:54 MST
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Gray@DSG.csc.ti.com, sandra%defun@cs.utah.edu,
Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Wed, 25 Jan 89 15:45 EST
> Which intuition are we talking about abandoning:
>
> Intuition #1: (DOTIMES (I 5) (PRINT (LOAD-TIME-VALUE (F))))
> evaluates the LOAD-TIME-VALUE expression only once.
↑↑↑↑
Don't you mean "at least" once here?
>
> Intuition #2: (DOTIMES (I 5) (PRINT (EVAL '(LOAD-TIME-VALUE (F)))))
> evaluates the LOAD-TIME-VALUE expression at least 5 times.
>
> I'm reluctant to abandon intuition #2 because I fear that it will complicate
> debugging tremendously. eg, if the dynamic state changes [eg, due to a bug
> fix] such that (F) can return a new value but it keeps returning an old value
> due to some hidden cache, I think the effects would be very frustrating.
I agree with you here. What I was envisioning as a solution to Moon's
objections is that if you had several references to the same (EQ)
LOAD-TIME-VALUE expression within a single call to EVAL, COMPILE, or
COMPILE-FILE, it would be OK to evaluate it only once, but that each call
to EVAL, COMPILE, or COMPILE-FILE would have to start out with a fresh
"cache". (No doubt somebody else can come up with some more elegant
verbiage to say this.)
-Sandra
-------
∂25-Jan-89 1421 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 9)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 25 Jan 89 14:21:03 PST
Received: by ti.com id AA08989; Wed, 25 Jan 89 16:18:55 CST
Received: from Kelvin by tilde id AA22682; Wed, 25 Jan 89 16:12:55 CST
Message-Id: <2810758325-10368547@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 25 Jan 89 16:12:05 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM,
CL-Compiler@SAIL.STANFORD.EDU
Subject: Re: Issue: LOAD-TIME-EVAL (Version 9)
In-Reply-To: Msg of Wed, 25 Jan 89 15:45 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> Which intuition are we talking about abandoning:
>
> Intuition #1: (DOTIMES (I 5) (PRINT (LOAD-TIME-VALUE (F))))
> evaluates the LOAD-TIME-VALUE expression only once.
>
> Intuition #2: (DOTIMES (I 5) (PRINT (EVAL '(LOAD-TIME-VALUE (F)))))
> evaluates the LOAD-TIME-VALUE expression at least 5 times.
Neither of these. The only problem case is when the same EQ expression is
referenced from two or more places in the code. Basically I think the
amendment would be to change the following paragraph:
Implementations must guarantee that each reference to a
LOAD-TIME-VALUE expression results in at least one evaluation of its
nested <form>. For example,
(DEFMACRO CONS-SELF (X)
`(CONS ,X ,X))
(CONS-SELF (LOAD-TIME-VALUE (COMPUTE-IT)))
must perform two calls to COMPUTE-IT; although there is only one
unique LOAD-TIME-VALUE expression, there are two distinct references
to it.
to something like:
Implementations are not required guarantee that each reference to a
LOAD-TIME-VALUE expression results in at least one evaluation of its
nested <form>. For example,
(DEFMACRO CONS-SELF (X)
`(CONS ,X ,X))
(CONS-SELF (LOAD-TIME-VALUE (COMPUTE-IT)))
may perform either one or two calls to COMPUTE-IT; although there is only
one unique LOAD-TIME-VALUE expression, there are two distinct references
to it.
∂25-Jan-89 1438 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 9)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Jan 89 14:38:03 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 526935; Wed 25-Jan-89 17:35:00 EST
Date: Wed, 25 Jan 89 17:35 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: LOAD-TIME-EVAL (Version 9)
To: Gray@DSG.CSC.TI.COM
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM,
Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: <2810758325-10368547@Kelvin>
Message-ID: <890125173503.1.KMP@BOBOLINK.SCRC.Symbolics.COM>
I think if you look again at my #2 it has the property you're alluding to,
since the repeat calls to EVAL constitute effectively distinct calls to
LOAD-TIME-EVAL. As such, the change you're proposing makes me equally nervous.
∂25-Jan-89 1621 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 9)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 25 Jan 89 16:21:21 PST
Received: by ti.com id AA09453; Wed, 25 Jan 89 17:48:03 CST
Received: from Kelvin by tilde id AA24799; Wed, 25 Jan 89 17:45:50 CST
Message-Id: <2810763895-10703198@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 25 Jan 89 17:44:55 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, sandra%defun@cs.utah.edu,
CL-Compiler@SAIL.STANFORD.EDU
Subject: Re: Issue: LOAD-TIME-EVAL (Version 9)
In-Reply-To: Msg of Wed, 25 Jan 89 17:35 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> I think if you look again at my #2 it has the property you're alluding to,
> since the repeat calls to EVAL constitute effectively distinct calls to
> LOAD-TIME-EVAL.
Oops; you're right - that is a problem.
I understand your concern about this point, but it doesn't look to me to
be any worse than what can already happen with displacing macros. I could
probably be persuaded that displacing macros should be outlawed, but that
should be a separate issue.
∂25-Jan-89 1631 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 25 Jan 89 16:31:28 PST
Received: by ti.com id AA09536; Wed, 25 Jan 89 18:03:09 CST
Received: from Kelvin by tilde id AA25068; Wed, 25 Jan 89 17:54:58 CST
Message-Id: <2810764452-10736661@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 25 Jan 89 17:54:12 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>,
Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.STANFORD.EDU
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
In-Reply-To: Msg of Wed, 25 Jan 89 14:52:54 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> What I was envisioning as a solution to Moon's
> objections is that if you had several references to the same (EQ)
> LOAD-TIME-VALUE expression within a single call to EVAL, COMPILE, or
> COMPILE-FILE, it would be OK to evaluate it only once, but that each call
> to EVAL, COMPILE, or COMPILE-FILE would have to start out with a fresh
> "cache".
But "within a single call to EVAL" would have to mean lexically within the
form being evaluated (you don't want to re-do LOAD-TIME-VALUEs within
evaluated functions called by the current form), so interpreted functions
would need to be thought of as closures over the cache. But you wouldn't
want that overhead on every interpreted function, so we're right back to
having the evaluator need to do a pre-pass on functions.
∂25-Jan-89 1646 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 25 Jan 89 16:43:53 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA23339; Wed, 25 Jan 89 17:41:58 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA20891; Wed, 25 Jan 89 17:41:47 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901260041.AA20891@defun.utah.edu>
Date: Wed, 25 Jan 89 17:41:45 MST
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>,
Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Wed, 25 Jan 89 17:54:12 CST
> But "within a single call to EVAL" would have to mean lexically within the
> form being evaluated (you don't want to re-do LOAD-TIME-VALUEs within
> evaluated functions called by the current form), so interpreted functions
> would need to be thought of as closures over the cache. But you wouldn't
> want that overhead on every interpreted function, so we're right back to
> having the evaluator need to do a pre-pass on functions.
Gack -- that's certainly not what I had in mind. Cacheing ought to be
an option, not a requirement. The current proposal explicitly says that
LOAD-TIME-VALUE expressions in the interpreter may be evaluated multiple
times, and I'm very much opposed to changing this.
If you don't want the overhead on an interpreted function, you should
COMPILE it. Given that interpreted code already runs something like
20 times slower than compiled, I can't take seriously arguments for
forcing cacheing of LOAD-TIME-VALUE expressions in interpreted
functions based on the performance considerations you cite.
-Sandra
-------
∂25-Jan-89 1732 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 25 Jan 89 17:30:16 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06124; 25 Jan 89 16:58 GMT
Date: Wed, 25 Jan 89 17:07:36 GMT
Message-Id: <20362.8901251707@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: sandra <@cs.utah.edu:sandra@defun>, cl-compiler@sail.stanford.edu
Cc: David N Gray <@NSS.Cs.Ucl.AC.UK:Gray@dsg.csc.ti.com>,
Cris Perdue <cperdue@sun.com>
> > I do not think it's reasonable to make the language weaker than the
> > source notation; and so I don't think *dump-circle* should exist
> > at all: it should always be as if it were true.
>
> Well, by this reasoning, *print-circle* shouldn't exist either.
My reasoning has nothing to do with *print-circle*. Compilation is
supposed to preserve the semantics of the language; PRINT is supposed
to print data objects so that they can be read back in by READ.
If the source code contains a constant, we have to say what
that means. We know the source code can be a list structure,
so we can say what the constant means in terms of that structure.
We can say it means "an equivalent object", where "equivalent"
is defined in some way. And, yes, we might rule out circularities.
But I think we should respect what the user can write as text source
even if the greater power of list-structure source is more than
we can handle. [and #. is an exception, I suppose.]
> I take it you would like to see another proposal added that requires the
> compiler to correctly handle circularity and sharing all the time?
What I'd like is for us to think about what we want compilation to
do first and let that drive the implementational details. I'm afraid
that we're letting the mechanics of compilation and interpretation
and fasloading distract us from semantics. The semantics must be
constrained by what we can reasonably implement, but we should try
to make them as consistent and uncluttered as we can.
I do not think implementation-oriented switches that change the
semantics are a good idea. If circular structures are something we
can handle, we should handle them. If not, we shouldn't. In neither
case should we have a switch. If the implementation cost is so high
that we feel we want to switch it off much of the time, we should
just not promise to handle circularities at all (in file compilation
anyway).
I do not think of *print-circle* as smething that changes the
semantics of constants. It just changes the actions of PRINT.
-- Jeff
∂25-Jan-89 1747 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 25 Jan 89 17:47:50 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA20330; Wed, 25 Jan 89 17:49:14 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA08523; Wed, 25 Jan 89 17:45:56 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA25261; Wed, 25 Jan 89 17:47:05 PST
Date: Wed, 25 Jan 89 17:47:05 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901260147.AA25261@clam.sun.com>
To: cl-compiler@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
This discussion, with an extra push from Jeff's last note, is pushing
us toward a DECLARATION about non-circular constants to help the
compiler/loader operate more efficiently. Agreed?
-Cris
∂25-Jan-89 1924 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 25 Jan 89 19:24:30 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA25787; Wed, 25 Jan 89 20:23:04 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA20991; Wed, 25 Jan 89 20:23:00 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901260323.AA20991@defun.utah.edu>
Date: Wed, 25 Jan 89 20:22:59 MST
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: cperdue@Sun.COM (Cris Perdue)
Cc: cl-compiler@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
In-Reply-To: cperdue@Sun.COM (Cris Perdue), Wed, 25 Jan 89 17:47:05 PST
To me, requiring a declaration for circular constants seems pretty
useless. I mean, it's not particularly difficult or time-consuming
for the compiler to detect that a constant is circular -- for example,
in the A-Lisp compiler it was trivial to add a check for this while
constants are being traversed and coalesced, and have it signal an
error. As I see it, the problem is the work required for implementors
to modify the compile-file/load interface not to build constants
bottom-up. The effort here is the same regardless of whether we
require circular constants to be handled all the time or just in some
cases. Having a flag or declaration does not reduce the amount of
effort, it just complicates the language unnecessarily. I personally
would find a simple statement that circular constants must be handled
by compile-file much less objectionable than all of these other
schemes that are being suggested.
-Sandra
-------
∂26-Jan-89 0558 CL-Compiler-mailer Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Jan 89 05:57:59 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 527202; Thu 26-Jan-89 08:54:40 EST
Date: Thu, 26 Jan 89 08:54 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
To: Gray@DSG.CSC.TI.COM
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM,
Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: <2810763895-10703198@Kelvin>
Message-ID: <890126085447.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Personally, I can't imagine how displacing macros can work at all.
The absence of user primitives for detecting which objects are read-only
means that user-written displacing macros must run up head-to-head with the
problem that they might displace quoted structure. Consider:
(DEFMACRO MYLET (&WHOLE FORM BVL &BODY FORMS)
(LET ((RESULT `((LAMBDA ,(MAPCAR #'CAR BVL) ,@FORMS)
,@(MAPCAR #'CADR BVL))))
(SETF (CAR FORM) (CAR RESULT))
(SETF (CDR FORM) (CDR RESULT))
FORM))
(EVAL '(MYLET ((X 3)) (+ X X)))
might end up losing due to displacing constant structure [the quoted
expression given to EVAL].
That leaves only system displacement. And I've always felt displacement was
so controversial that no user base would put up with it simply being dumped
on them. Rel6 of Symbolics Genera decided to displace just a few forms [LET,
LAMBDA, DO, ...] and it caused massive outcries from customers because it
broke all kinds of code. Symbolics withdrew the `feature' in Rel7.
The only way I can imagine people living with it is if they grew up with it,
but since it's a given that people in other environments didn't grow up with
it, then most portable code [I suspect] is not ready to deal with it.
There's actually one other option: The system provides a switch so you can
enable the `feature' if you want it. That reduces to the same, though,
because you just can't let users unilaterally set a variable [or whatever]
to change the semantics of the running Lisp for his application's needs and
expect that all the supporting libraries that he wrote will just continue
to function normally. It may be that the only reason that the switch has not
been set already is that one of those libraries left it off for a reason.
More and more these days I'm left with the feeling that all option variables
should be handled by vote. People (i.e., code modules) should identify their
preferrences without erradicating pre-declared preferences. As long as there
are no conflicts, the requested options should be permitted. But if there
is a conflict, the system should throw up its arms in dispair rather than
try to arbitrarily side with one faction or another. If we did this, I think
it would become quickly apparent that displacing macros were a thing we
should eliminate because no one would be able to figure out how to use them
in any serious way.
But this whole sub-issue aside, all we're really saying is that LOAD-TIME-VALUE
should not be done by displacing.
∂26-Jan-89 0711 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Jan 89 07:11:02 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 527221; Thu 26-Jan-89 10:08:06 EST
Date: Thu, 26 Jan 89 10:08 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: cperdue@Sun.COM
cc: cl-compiler@sail.stanford.edu,
jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
In-Reply-To: <8901260147.AA25261@clam.sun.com>
Message-ID: <890126100807.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Wed, 25 Jan 89 17:47:05 PST
From: cperdue@Sun.COM (Cris Perdue)
This discussion, with an extra push from Jeff's last note, is pushing
us toward a DECLARATION about non-circular constants to help the
compiler/loader operate more efficiently. Agreed?
You don't see me agreeing.
There is no evolved way to name a piece of data, other than a variable,
so it's a bit hard to declare it. If it's gotten as far as being in a
variable, it's probably not being dumped. The constants being dumped are
generally anonymous. Somehow the idea of doing
(DEFUN FOO () (DEFUN FOO ()
(LET ((X '#1=(A . #1#))) or (LET ((X #1=3))
(DECLARE (CIRCULAR #1#)) (DECLARE (NON-CIRCULAR #1#))
...)) ...))
doesn't appeal to me.
Or maybe you only meant to say:
(DEFUN FOO ()
(DECLARE (HAS-NO-CIRCULAR-CONSTANTS))
(LOOP (FOO)))
but how do you know that (LOOP (FOO)) doesn't expand into
(BLOCK NIL (MAPCAR #'(LAMBDA (#:IGNORE) (FOO)) '#1=(A . #1#)))
? This would almost work if you required the LOOP expansion to be
(LOCALLY
(DECLARE (WELL-YES-IT-REALLY-DOES-HAVE-CIRCULAR-CONSTANTS-AFTER-ALL))
(BLOCK NIL (MAPCAR #'(LAMBDA (#:IGNORE) (FOO)) '#1=(A . #1#))))
but then suddenly the burden is on the person using these things to
declare them rather than the burden being on the person who wants speed
to declare something that gets it for him, and that's the part I want
to avoid [for internal consistency with, for example, numbers where
the basic model is simple and you add declarations to get a hairier
model but more efficiency].
I guess I don't see any way that declarations are going to do anything
but confuse matters even more.
∂26-Jan-89 0835 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
Received: from ti.com by SAIL.Stanford.EDU with TCP; 26 Jan 89 08:35:22 PST
Received: by ti.com id AA11982; Thu, 26 Jan 89 10:34:07 CST
Received: from Kelvin by tilde id AA11432; Thu, 26 Jan 89 10:27:36 CST
Message-Id: <2810823991-14313836@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 26 Jan 89 10:26:31 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU
Subject: Re: Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
In-Reply-To: Msg of Thu, 26 Jan 89 08:54 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> That leaves only system displacement. And I've always felt displacement was
> so controversial that no user base would put up with it simply being dumped
> on them. Rel6 of Symbolics Genera decided to displace just a few forms [LET,
> LAMBDA, DO, ...] and it caused massive outcries from customers because it
> broke all kinds of code. Symbolics withdrew the `feature' in Rel7.
> The only way I can imagine people living with it is if they grew up with it,
> but since it's a given that people in other environments didn't grow up with
> it, then most portable code [I suspect] is not ready to deal with it.
We inherited an implementation that uses displacing macros, and it has
caused some problems for a few users, but there haven't been "massive
outcries". I can see, though, that this is probably not the best way to
do things.
> But this whole sub-issue aside, all we're really saying is that LOAD-TIME-VALUE
> should not be done by displacing.
But other things can be? I think we should be consistent -- either
displacement is a valid implementation technique or it isn't. I don't see
how the case of evaluating the expression in a LOAD-TIME-VALUE form is
fundamentally different from the more important question of when and how
many times a macro expander is invoked. If your interpreter
implementation does a pre-pass, then you want to do both during the
pre-pass, while a displacing macro implementation would want to use the
same displacement mechanism for both.
∂26-Jan-89 0933 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 26 Jan 89 09:32:58 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA07584; Thu, 26 Jan 89 09:33:45 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA29658; Thu, 26 Jan 89 09:30:23 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA25856; Thu, 26 Jan 89 09:31:32 PST
Date: Thu, 26 Jan 89 09:31:32 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901261731.AA25856@clam.sun.com>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Cc: cl-compiler@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Regarding Sandra's comment on the uselessness of a declaration
for circular constants: I was thinking of something to declare
NON-circular constants to save the compiler and loader's effort.
The difference is that such a declaration could be considered
optional.
Regarding Kent's comments:
"constants being dumped are generally anonymous"
Yes, I agree.
Kent comments on the interaction of macros with a declaration
covering all literal constants in a lexical scope.
Once again he is right in the sense that there can be interaction.
That is an issue that I didn't consider properly before throwing
out my suggestion. A couple of comments:
1) It seems to me that a construct informing the compiler about
circularity with a lexical scope (such as a declaration) is strictly
more powerful than any flag. A flag would presumably only apply on
basically a "per top level form" granularity. Therefore, if a
declaration won't work, a flag won't work.
2) One could add an option to QUOTE as an alternative, e.g.:
(QUOTE (A B C) :CIRCULAR NIL)
or something like that. This would deal with Kent's points.
At first I didn't like this at all on the grounds that it would
make people write extra crud all over their constants to make
the compiler and loader run faster. On second thought it appeals
to me much more.
Suppose the default value of the option supports circularity:
It may be that putting the option in explicitly would only
be important for a few constants that are large. I think
that wouldn't be so bad.
Suppose the default option does NOT support circularity:
One probably knows when one is making a potentially circular constant.
This is almost always done by a program, so it is easy to
specify the option without crudding up source code.
∂26-Jan-89 1016 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Jan 89 10:15:54 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 527376; Thu 26-Jan-89 13:13:15 EST
Date: Thu, 26 Jan 89 13:13 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: cperdue@Sun.COM
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, cl-compiler@sail.stanford.edu,
jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
In-Reply-To: <8901261731.AA25856@clam.sun.com>
Message-ID: <890126131316.5.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Thu, 26 Jan 89 09:31:32 PST
From: cperdue@Sun.COM (Cris Perdue)
... One could add an option to QUOTE as an alternative, e.g.:
(QUOTE (A B C) :CIRCULAR NIL)
or something like that. ...
I don't think I buy this idea, but I do admit to getting quite a
chuckle out of it. It's very original.
Aside from some aesthetic objections, and the fact that you're changing
one of the most fundamental functions in all of Lisp in a way that
would probably make people queasy, the main serious objection
is that it doesn't interface to ' well. To get any benefit, you'd
be forced to convert most quoted constants to be written long-hand,
and drastically pessimize code readability.
If you don't make it the default, then the presence of #= and ##
just invite people to lose.
If you change ' to conspire with #=, ##, #., etc. and make ' expand
into something different when they are present, you'll probably hear
from an entire community you never knew about who does embedded
languages where 'X is not interpreted by Lisp at all, and where
(QUOTE ... :CIRCULAR NIL/T) would not be a happy thing for the embedded
language to come across. Interdialect compatibility [eg, Scheme<->Lisp
or Zetalisp<->Common-Lisp] are the best examples of this I can think
of, but I've seen other uses.
But as an aside, I do note one benefit of your proposed change: it
would make the problem of side-effecting quoted constants very apparent.
After all, it would be easy to explain to people how things like:
(LET ((X (QUOTE (A) :CIRCULAR NIL)))
(RPLACD X X))
could lead to trouble! :-)
∂26-Jan-89 1029 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 26 Jan 89 10:29:12 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA09625; Thu, 26 Jan 89 10:29:57 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA03563; Thu, 26 Jan 89 10:26:27 PST
Received: by clam.sun.com (3.2/SMI-3.2)
id AA25985; Thu, 26 Jan 89 10:27:37 PST
Date: Thu, 26 Jan 89 10:27:37 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901261827.AA25985@clam.sun.com>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Cc: cl-compiler%clam@Sun.COM
> ... One could add an option to QUOTE as an alternative, e.g.:
>
> (QUOTE (A B C) :CIRCULAR NIL)
>
> or something like that. ...
>
> I don't think I buy this idea, but I do admit to getting quite a
> chuckle out of it. It's very original. . . .
In my opinion Kent's note does not address the main issues.
In no case do I see any need for an explicit option in most constants.
As a language user I don't feel a need for any options. It's
fine with me if we can simply allow all constants to be circular.
If something is needed, let's try to provide it.
∂26-Jan-89 1033 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 26 Jan 89 10:32:11 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA12483; Thu, 26 Jan 89 11:26:42 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA21425; Thu, 26 Jan 89 11:25:32 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901261825.AA21425@defun.utah.edu>
Date: Thu, 26 Jan 89 11:25:30 MST
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: cperdue@Sun.COM
Cc: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>,
cl-compiler@sail.stanford.edu,
jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Thu, 26 Jan 89 13:13 EST
Do I need to make some more retching noises? :-) :-)
Seriously, I think this whole discussion is wandering off track. The
real question is whether it is legal to put a circular object in a
constant seen by COMPILE-FILE. It either is, or it isn't.
Introducing a mechanism that might make it possible for compilers to
process some constants more efficiently is a separate, and I think
secondary issue.
-Sandra
-------
∂26-Jan-89 1034 CL-Compiler-mailer issue COMPILER-DIAGNOSTICS, version 9
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 26 Jan 89 10:33:56 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA12639; Thu, 26 Jan 89 11:32:29 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA21444; Thu, 26 Jan 89 11:32:26 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901261832.AA21444@defun.utah.edu>
Date: Thu, 26 Jan 89 11:32:22 MST
Subject: issue COMPILER-DIAGNOSTICS, version 9
To: cl-compiler@sail.stanford.edu
Here is a much simplified proposal on this issue. It removes all the
stuff relating to the NOTICE condition, and incorporates suggestions
from Pitman and Barrett on removing the :HANDLER argument to
COMPILE-FILE.
Forum: Compiler
Issue: COMPILER-DIAGNOSTICS
References: CLtL p. 438-439, 62, 69, 160, 161
Condition System, Revision #18
S:>KMP>cl-conditions.text.34
Issue GC-MESSAGES
Issue RETURN-VALUES-UNSPECIFIED
Issue COMPILER-VERBOSITY
Category: CLARIFICATION, ENHANCEMENT
Edit History: V1, 15 Oct 1988, Sandra Loosemore
V2, 19 Oct 1988, Sandra Loosemore (minor fixes)
V3, 25 Oct 1988, Sandra Loosemore (input from Pitman & Gray)
V4, 01 Nov 1988, Sandra Loosemore (fix typos)
V5, 15 Dec 1988, Dan L. Pierson (new condition types)
V6, 15 Dec 1988, Sandra Loosemore (additions, fix wording)
V7, 16 Dec 1988, Dan L. Pierson (minor cleanup)
V8, 07 Jan 1989, Sandra Loosemore (expand discussion)
V9, 26 Jan 1989, Sandra Loosemore (simplify)
Status: **DRAFT**
Problem Description:
It is unclear whether various diagnostics issued by the compiler are
supposed to be true errors and warnings, or merely messages.
In some implementations, COMPILE-FILE handles even serious error
situations (such as syntax errors) by printing a message and then
trying to recover and continue compiling the rest of the file, rather
than by signalling an error. While this user interface style is just
as acceptable as invoking the debugger, it means that a normal return
from COMPILE-FILE does not necessarily imply that the file was
successfully compiled.
Many compilers issue warnings about programming style issues (such as
binding a variable that is never used but not declared IGNORE).
Sometimes these messages obscure warnings about more serious problems,
and there should be some way to differentiate between the two. For
example, it should be possible to suppress the style warnings.
Also, neither CLtL nor issue RETURN-VALUES-UNSPECIFIED states what the
return value from COMPILE-FILE should be.
Proposal COMPILER-DIAGNOSTICS:USE-HANDLER:
(1) Introduce a new condition type, STYLE-WARNING, which is a subtype
of WARNING.
(2) Clarify that ERROR and WARNING conditions may be signalled within
COMPILE or COMPILE-FILE, including arbitrary errors which may
occur due to compile-time processing of (EVAL-WHEN (COMPILE) ...)
forms or macro expansion.
Considering only those conditions signalled -by- the compiler (as
opposed to -within- the compiler),
(a) Conditions of type ERROR may be signalled by the compiler in
situations where the compilation cannot proceed without
intervention.
Examples:
file open errors
syntax errors
(b) Conditions of type WARNING may be signalled by the compiler in
situations where the standard explicitly states that a warning must,
should, or may be signalled; and where the compiler can determine
that a situation that "is an error" would result at runtime.
Examples:
violation of type declarations
SETQ'ing or rebinding a constant defined with DEFCONSTANT
calls to built-in Lisp functions with wrong number of arguments
or malformed keyword argument lists
referencing a variable declared IGNORE
unrecognized declaration specifiers
(c) The compiler is permitted to signal diagnostics about matters of
programming style as conditions of type STYLE-WARNING. Although
STYLE-WARNINGs -may- be signalled in these situations, no
implementation is -required- to do so. However, if an
implementation does choose to signal a condition, that condition
will be of type STYLE-WARNING and will be signalled by a call to
the function WARN.
Examples:
redefinition of function with different argument list
unreferenced local variables not declared IGNORE
declaration specifiers described in CLtL but ignored by
the compiler
(3) Require COMPILE and COMPILE-FILE to handle the ABORT restart by
aborting the smallest feasible part of the compilation. State that
both COMPILE and COMPILE-FILE are allowed to establish a default
condition handler. If such a condition handler is established,
however, it must first resignal the condition to give any
user-established handlers a chance to handle it. If all user error
handlers decline, the default handler may handle the condition in an
implementation-specific way; for example, it might turn errors into
warnings.
(4) Specify that COMPILE-FILE returns two values. The first value
is the truename of the output file, or NIL if the file could not be
created. The second value is T if the file was compiled without
errors, or NIL if errors were signalled during compilation.
Rationale:
Introducing the STYLE-WARNING condition allows handlers to distinguish
between potentially serious problems and mere kibitzing on the part of
the compiler.
Requiring any condition handlers established by the compiler to resignal
the condition before proceeding with any implementation-specific action
gives user error handlers a chance to override the compiler's default
behavior. For example, the user error handler could invoke a restart
such as ABORT or MUFFLE-WARNING.
Requiring the compiler to handle the ABORT restart reflects what
several implementations already do (although probably not using this
mechanism). The intent of the wording is to allow an implementation
to abort the entire compilation if it is not feasible to abort a
smaller part.
Requiring a second success-p value to be returned from COMPILE-FILE
gives the user some indication of whether there were serious problems
encountered in compiling the file.
Test Case/Example:
Here is an example of how COMPILE-FILE might set up its condition
handlers. It establishes an ABORT restart to abort the compilation
and a handler to take implementation-specific action on ERROR
conditions. Note that INTERNAL-COMPILE-FILE may set up additional
ABORT restarts.
(defvar *output-file-truename* nil)
(defun compile-file (input-file &key output-file)
(let ((*output-file-truename* nil)
(errors-detected nil))
(with-simple-restart (abort "Abort compilation.")
(handler-bind ((error #'(lambda (condition)
(setq errors-detected t)
(signal condition)
...)))
(internal-compile-file input-file output-file)))
(values *output-file-truename*
errors-detected)))
Current Practice:
No implementation behaves exactly as specified in this proposal.
In VaxLisp, COMPILE-FILE handles most compile-time errors without
invoking the debugger. (It gives up on that top-level form and moves on
to the next one.) Instead of signalling errors or warnings, it simply
prints them out as messages.
In Lucid Common Lisp, COMPILE-FILE invokes the debugger when it encounters
serious problems. COMPILE-FILE returns the pathname for the output file.
Symbolics Genera usually tries to keep compiling when it encounters errors;
so does Symbolics Cloe.
On the TI Explorer, the compiler tries to catch most errors and turn
them into warnings (except for errors on opening a file), but the user
can change special variable COMPILER:WARN-ON-ERRORS to NIL if he wants
to enter the debugger on an error signalled during reading, macro
expansion, or compile-time evaluation. The true name of the output
file is returned as the first value. A second value indicates whether
any errors or warnings were reported.
IIM Common Lisp's compiler handles errors using a resignalling mechanism
similar to what is described here.
Cost to implementors:
The cost to implementors is not trivial but not particularly high. This
proposal tries to allow implementations considerable freedom in what
kinds of conditions the compiler must detect and how they are handled,
while still allowing users some reasonably portable ways to deal with
compile-time errors.
Cost to users:
This is a compatible extension. This proposal may cause users to see
some small differences in the user interface to the compiler, but
implementations already vary quite widely in their approaches. Some
users will probably have to make some minor changes to their code.
Adding the STYLE-WARNING type may cause conflicts with programs
already using that name.
Benefits:
Users are given a way to detect and handle compilation errors, which
would simplify the implementation of portable code-maintenance
utilities. The behavior of the compiler in error situations is made
more uniform across implementations.
Discussion:
The issue of whether the compiler may print normal progress messages
is discussed in detail in a separate issue, COMPILER-VERBOSITY.
-------
∂26-Jan-89 1039 CL-Compiler-mailer Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Jan 89 10:39:23 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 527405; Thu 26-Jan-89 13:35:54 EST
Date: Thu, 26 Jan 89 13:36 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
cc: Gray@DSG.CSC.TI.COM, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <890126085447.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-ID: <19890126183619.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 26 Jan 89 08:54 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Personally, I can't imagine how displacing macros can work at all.
Displacing macros do not work in Common Lisp, period. Not only for
the reasons you cited, but also because of lexical scoping (mentioned
in a recent message from me, I won't bore you by repeating it).
∂26-Jan-89 1045 CL-Compiler-mailer issue COMPILER-VERBOSITY, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 26 Jan 89 10:44:56 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA13155; Thu, 26 Jan 89 11:43:28 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA21466; Thu, 26 Jan 89 11:43:22 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901261843.AA21466@defun.utah.edu>
Date: Thu, 26 Jan 89 11:43:21 MST
Subject: issue COMPILER-VERBOSITY, version 6
To: cl-compiler@sail.stanford.edu
Here's a new draft on this issue. It removes the USE-CONDITIONS
proposal and incorporates Moon's suggestion for LIKE-LOAD.
Forum: Compiler
Issue: COMPILER-VERBOSITY
References: CLtL p. 438-329; 426
issue COMPILER-DIAGNOSTICS
Category: ENHANCEMENT
Edit History: V1, 25 Oct 1988, Sandra Loosemore
V2, 12 Dec 1988, Dan L. Pierson (add USE-CONDITIONS)
V3, 15 Dec 1988, Dan L. Pierson (expand on conditions)
V4, 21 Dec 1988, Dan L. Pierson (reword and clarify)
V5, 06 Jan 1989, Sandra Loosemore (update discussion)
V6, 26 Jan 1989, Sandra Loosemore (remove USE-CONDITIONS)
Status: **DRAFT**
Problem Description:
Implementations vary widely in the amount of information that is printed
out by COMPILE-FILE. In some situations, it would be useful to control
how much information is printed.
Proposal COMPILER-VERBOSITY:LIKE-LOAD:
Introduce special variables, *COMPILE-VERBOSE* and *COMPILE-PRINT*,
with implementation-dependent initial values.
Add :VERBOSE and :PRINT keyword arguments to the function
COMPILE-FILE, analogous to those for the function LOAD.
The :VERBOSE argument (which defaults to the value of
*COMPILE-VERBOSE*), if true, permits COMPILE-FILE to print a message
in the form of a comment to *STANDARD-OUTPUT* indicating what file is
being compiled and other useful information.
The :PRINT argument (which defaults to the value of *COMPILE-PRINT*),
if true, causes information about top-level forms in the file being
compiled to be printed to *STANDARD-OUTPUT*. Exactly what is printed
will vary from implementation to implementation, but nevertheless some
information will be printed.
Introduce a special variable *LOAD-PRINT*, which has an initial value of
NIL. State that the default value of the :PRINT argument to LOAD is
*LOAD-PRINT* (rather than NIL).
Rationale:
This proposal makes COMPILE-FILE behave like LOAD. There is already
some precedent for doing this (for example, issue COMPILE-FILE-PACKAGE,
which makes COMPILE-FILE as well as LOAD rebind *PACKAGE*).
Adding the *LOAD-PRINT* variable allows the printing of messages by
LOAD to be controlled either on a global or a per-call basis.
Current Practice:
COMPILE-FILE prints out progress messages in nearly all
implementations.
Lucid provides a :MESSAGES keyword argument to COMPILE-FILE, which can
either be a stream to send messages to, or NIL to suppress messages.
The default value is T, which sends messages to "the standard terminal
device".
On the TI Explorer, COMPILE-FILE displays the name of the function
being compiled when the option :VERBOSE T is given or special variable
COMPILER:COMPILER-VERBOSE is true. (In other words, they use :VERBOSE
to mean what this proposal says to use :PRINT for.)
Symbolics Cloe already has a *LOAD-PRINT* variable.
Cost to implementors:
This is an incompatible change for some implementations. While the
changes required should be conceptually simple, their implementation
may involve a significant amount of grunt work. At least two
implementations already provide some similar mechanism for suppressing
messages.
Cost to users:
Some (non-portable) user code may break in implementations where this
is an incompatible change.
No user code should be broken by the addition of the *LOAD-PRINT*
variable, since the default behavior for the :PRINT keyword to LOAD
is unchanged.
Benefits:
Users are given a portable way to control how much information is printed
by COMPILE-FILE.
Discussion:
This issue addresses an extension to the language. If this proposal
is not accepted, the standard will simply continue not to say anything
about whether COMPILE-FILE can print progress messages, or what stream
such messages are directed to.
-------
∂26-Jan-89 1225 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 26 Jan 89 12:24:57 PST
Received: from pitney-bowes ([192.9.200.50]) by heavens-gate.lucid.com id AA10584g; Thu, 26 Jan 89 12:17:22 PST
Received: by pitney-bowes id AA10651g; Thu, 26 Jan 89 12:16:11 PST
Date: Thu, 26 Jan 89 12:16:11 PST
From: Jim McDonald <jlm@lucid.com>
Message-Id: <8901262016.AA10651@pitney-bowes>
To: sandra%defun@cs.utah.edu
Cc: cperdue@Sun.COM, KMP@STONY-BROOK.SCRC.Symbolics.COM,
cl-compiler@sail.stanford.edu,
jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
In-Reply-To: Sandra J Loosemore's message of Thu, 26 Jan 89 11:25:30 MST <8901261825.AA21425@defun.utah.edu>
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 4
I agree with Sandra. If COMPILE-FILE is required to handle
circularities in some cases, then it is not worth worrying about the
marginal speed improvements that might be obtained by declarations of
(non-)circularity.
(A) Jonl may correct me, but I think the experience at Lucid has
been that the overhead per constant for detecting circularities
is minor, perhaps down in the noise.
(B) Circular data is rare.
(C) Time spent compiling code (as opposed to running it) is rarely
critical.
The pain involved in handling circular data is felt almost entirely by
the person who writes and debugs the faslout code. (The basic ideas
are simple, but given the wealth of data types in common lisp, there
are a lot of special cases, each of which can potentially be miscoded.)
Nonetheless, there are existance proofs that people survive the
experience and that robust code emerges.
I think any serious implementation of COMPILE-FILE will quietly handle
circular data, just as any serious garbage collector is expected to.
jlm
∂26-Jan-89 1258 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 26 Jan 89 12:58:22 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA17763; Thu, 26 Jan 89 13:49:29 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA21550; Thu, 26 Jan 89 13:47:54 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901262047.AA21550@defun.utah.edu>
Date: Thu, 26 Jan 89 13:47:53 MST
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: Jim McDonald <jlm@lucid.com>
Cc: sandra%defun@cs.utah.edu, cperdue@Sun.COM,
KMP@STONY-BROOK.SCRC.Symbolics.COM, cl-compiler@sail.stanford.edu,
jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
In-Reply-To: Jim McDonald <jlm@lucid.com>, Thu, 26 Jan 89 12:16:11 PST
Is there anybody who would still prefer the *DUMP-CIRCLE* proposal to
one that simply says that COMPILE-FILE must handle circularities and
shared structure properly all the time? That way we would have three
proposals covering a range of possibilities: no sharing, no
circularity; sharing but not circularity; and both sharing and
circularity.
-Sandra
-------
∂26-Jan-89 1653 CL-Compiler-mailer Re: DEFMETHOD compile-time processing
Received: from ti.com by SAIL.Stanford.EDU with TCP; 26 Jan 89 16:53:20 PST
Received: by ti.com id AA14157; Thu, 26 Jan 89 18:47:38 CST
Received: from Kelvin by tilde id AA23034; Thu, 26 Jan 89 18:38:20 CST
Message-Id: <2810853419-16115524@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 26 Jan 89 18:36:59 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Patrick Dussud <dussud@lucid.com>
Cc: Common-Lisp-Object-System@SAIL.Stanford.edu, CL-Compiler@SAIL.Stanford.edu
Subject: Re: DEFMETHOD compile-time processing
In-Reply-To: Msg of Tue, 24 Jan 89 09:19:45 PST from Patrick Dussud <dussud@lucid.com>
> The general issue that we try to address is that it should be possible for
> some implementations to precompute a certain number of characteristic of CLOS
> programs at compile-file time. These precomputation involve metaobjects
> (looking at user class definitions, method object, generic functions) in a
> state that should be close enough to their state when the program is loaded in
> the remote environment. It is not generally possible to simulate the remote
> environment as far as running remote code. Therefore, precomputation at
> compile time, by doing metaprogramming on remote environment objects is more
> restrictive that doing metaprogramming on local environment objects. However,
> we don't want to introduce two distinct metaprogrammings. Chapter 3 is trying
> to unify remote and local metaprogramming. All the side effect that are done
> when the program is loaded, is simulated in the remote environment(
> Add-method, ensure-class...).
I think I see the principle you're presenting here, but I'm still not
clear on how it applies to this case. The calls to MAKE-METHOD-LAMBDA and
ADD-METHOD are done by the implementation of the DEFMETHOD macro or its
expansion, and the Meta-Object Protocol doesn't specify any intermediate
points at which the user can get involved. Under what circumstances would
the user know or care whether the compiler called ADD-METHOD? Sure, I
suppose that a macro could use ENSURE-GENERIC-FUNCTION to look up the
compile-time definition, invoke FIND-METHOD or GENERIC-FUNCTION-METHODS,
and then look at the method objects, but is there really any reason to
want to do that? Given the precedent that certain operations are not
valid on uninitialized objects or un-finalized classes, who would be hurt
if we said that FIND-METHOD and GENERIC-FUNCTION-METHODS were not valid on
generic functions in the remote environment?
Looking some more at pages 3-16 and 3-17, I think it's interesting that it
doesn't really say anything about compilation, just about the side effects
of what the compiler does. Presumably the lambda expression computed at
compile time by MAKE-METHOD-LAMBDA is compiled, and the resulting compiled
function is what is actually used in the run-time call to MAKE-INSTANCE
for the method.
There appears to be an additional problem, though, in that the
compile-time call to MAKE-METHOD-LAMBDA depends on the result of
GENERIC-FUNCTION-METHOD-CLASS, yet it is specified that
GENERIC-FUNCTION-METHOD-CLASS is called again at load time. If we can't
assume that the value will be the same, then what does that say about the
validity of the compiled method function? It looks like either you don't
want to do it again at load time, or else you do it again in order to
signal an error if it doesn't match the compile-time value.
Also aside from the question of lexical environments is the issue of
control flow context. There has been discussion in the compiler committee
that seems to have come to the conclusion that we don't want things like
DEFMACRO side-effecting the compile-time environment if they are embedded
in a function or conditional such that they really happen at some
indeterminate run time rather than when the file is loaded. The same
consideration would apply to DEFCLASS, DEFGENERIC, and DEFMETHOD. This
requires being able to conceptually separate the actions needed to compile
the run-time code from the actions simulating what happens at load time.
And yet another issue: if the user says
(EVAL-WHEN (EVAL COMPILE LOAD)
(DEFMETHOD ...))
because he really does want to call that generic function from one of his
macros, does that mean that the compile-time ADD-METHOD in this case needs
to be to the resident installed definition instead of the remote
environment? Or is this not legal?
∂26-Jan-89 1856 CL-Compiler-mailer Issues: DEFINING-MACROS-NON-TOP-LEVEL, EVAL-WHEN-NON-TOP-LEVEL, COMPILED-FUNCTION-REQUIREMENTS
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Jan 89 18:56:27 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 527989; Thu 26-Jan-89 21:54:33 EST
Date: Thu, 26 Jan 89 21:55 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issues: DEFINING-MACROS-NON-TOP-LEVEL, EVAL-WHEN-NON-TOP-LEVEL, COMPILED-FUNCTION-REQUIREMENTS
To: CL-Compiler@SAIL.STANFORD.EDU
cc: Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <19890125031316.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890127025502.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 24 Jan 89 22:13 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
We have a lot to say on these three topics but I've run out of time. I'm
just sending this note so you know to expect something on these three,
most likely on Wednesday or Thursday of this week.
I haven't had time to do much Common Lisp stuff since Tuesday, so "there
will a short delay".
On EVAL-WHEN-NON-TOP-LEVEL, I prefer a proposal by KMP that you haven't seen
yet which is still being debugged.
DEFINING-MACROS-NON-TOP-LEVEL has some minor problems with which forms
have top-level bodies (I agree with IIM that MACROLET and SYMBOL-MACROLET
should have top-level bodies, and I've pointed out that LOCALLY should),
also it needs to clarify whether one top-level form is processed before
the next is read (can I do a DEFSTRUCT and then use that structure's
name in a #S in the next form? seems reasonable to want to do that.).
However, it has a major problem of defining what lexical environment
things are in, and I don't think what you have now is right. I'll
comment in detail later.
I'd like to point out that the defining characteristic of top-level is
not that the lexical environment is null, but that the lexical environment
does not contain any variables, functions, blocks, or go tags; it
contains only declarations, macros, and the COMPILE-FILE remote/local
environment business. Also top-level is not nested inside any flow
of control (conditionals, iterations, catches [which are essentially
a kind of conditional]); that's why the compiler can treat defmacro,
for example, specially at top level, because it knows that the defmacro
will be executed exactly once at load time and in a fully known lexical
environment.
COMPILED-FUNCTION-REQUIREMENTS: this has some bad problems with closures,
and also needs to wait until EVAL-WHEN is settled. More later.
∂27-Jan-89 0244 CL-Compiler-mailer Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 27 Jan 89 02:44:39 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA13592g; Fri, 27 Jan 89 02:39:05 PST
Received: by bhopal id AA17581g; Fri, 27 Jan 89 02:41:25 PST
Date: Fri, 27 Jan 89 02:41:25 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901271041.AA17581@bhopal>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Kent M Pitman's message of Wed, 25 Jan 89 12:11 EST <890125121120.8.KMP@BOBOLINK.SCRC.Symbolics.COM>
Subject: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
re: The problem is that a lot of copying advocates have been going around
trying to use "the need for copying" as leverage for restricting
the set of things which I may quote. My view is that it is my write
to quote whatever I want, and it's up to the person who thinks they
can do something fun with copying to not get themselves in deeper than
they can handle.
Kent, I agree with you 100% on this (your "point 2"; modulo typos, of course).
It looks like you and I may be in agreement about this whole issue.
-- JonL --
∂27-Jan-89 1719 CL-Compiler-mailer Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 89 17:19:13 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 528624; Fri 27-Jan-89 20:15:40 EST
Date: Fri, 27 Jan 89 20:16 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Sandra J Loosemore <sandra%defun@cs.utah.edu>,
Jon L White <jonl@lucid.com>, Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>,
Cris Perdue <cperdue@Sun.COM>
cc: CL-Compiler@SAIL.STANFORD.EDU, Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <19890125031059.3.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<8901250447.AA20141@defun.utah.edu>,
<8901251310.AA08200@bhopal>,
<890125121120.8.KMP@BOBOLINK.SCRC.Symbolics.COM>,
<8901251757.AA24301@clam.sun.com>,
<8901271041.AA17581@bhopal>
Message-ID: <19890128011607.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
If I may summarize what I see as the key points in this discussion:
No one wants EVAL and COMPILE to be specified to be different in this
respect (i.e. drop QUOTE-MAY-COPY:NOT-EVAL).
The output of LOAD-TIME-EVAL is not subject to copying.
The point of controversy is whether we allow a copy of some sort to be
done between the time a list structure is made into a function (or
passed as a form to EVAL) and the time of completion of the first
evaluation of a (quoted or self-evaluating) constant in the function (or
form). Side-effects on these objects are not allowed, so the issue is
only identity under EQL. A clean language would not allow such copying,
but copying can be desirable for implementation reasons in some
implementations and is already done in much current practice.
There should be no restriction on the data types or circularity of
objects used as constants outside of COMPILE-FILE. If copying is
allowed it happens only for objects that the implementation is capable
of copying without signalling an error or doing anything undefined, and
without violating "similarity as constants within a single Lisp", a
concept to be defined by CONSTANT-COMPILABLE-TYPES.
I would vote either for a proposal to forbid copying, or for a
proposal to allow it within the above restrictions.
Two observations:
The "similarity as constants within a single Lisp" rule means that
instances of user-defined STANDARD-CLASS or STRUCTURE-CLASS types
are never copied. This removes my largest objection to copying.
(LOAD-TIME-VALUE (QUOTE <foo>)) is not a way to prevent <foo>
from being copied; the output from LOAD-TIME-VALUE is not copied,
but the input might be.
∂27-Jan-89 1812 CL-Compiler-mailer Re: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 89 18:12:20 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 528642; Fri 27-Jan-89 21:10:02 EST
Date: Fri, 27 Jan 89 21:10 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: CL-Compiler@SAIL.STANFORD.EDU, Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8901251616.AA20436@defun.utah.edu>
Message-ID: <19890128021036.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 25 Jan 89 09:16:50 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Tue, 24 Jan 89 21:10 EST
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> This is said to be a clarification, but I believe it is a change because
> it makes the default semantics very different from the NOTINLINE
> semantics (items 2b and 2c). However, I can't find anything in CLtL
> that's contradicted by this proposal.
I suppose the most consistent specification would be to only allow
tail recursion optimization in the -presence- of an INLINE
declaration. But I think the current wording of item 2b more closely
represents current practice. It's how A-Lisp and Utah Common Lisp
work, and I think VaxLisp does this also. The rather ancient version
of Lucid Lisp I have seems to do tail recursion optimization even if
you proclaim the function NOTINLINE. Is there some other particular
behavior you'd like to see specified instead?
Not really. On the whole I would prefer that user-defined functions are
NOTINLINE by default, and only an INLINE declaration allows the compiler
to assume that the function<->function-name association will not change.
However, I'm not strongly opposed to your idea of introducing a third
state in addition to INLINE and NOTINLINE, and making it the default.
Item 2c (block compilation) has been more controversial
I cannot think of any believable justification for favoring tail
recursion in the absence of an INLINE declaration yet opposing block
compilation in the absence of an INLINE declaration. I think we should
either allow neither or allow both.
∂27-Jan-89 1905 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 89 19:05:48 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 528656; Fri 27-Jan-89 22:03:02 EST
Date: Fri, 27 Jan 89 22:03 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: David N Gray <Gray@DSG.csc.ti.com>, Sandra J Loosemore <sandra%defun@cs.utah.edu>,
KMP@STONY-BROOK.SCRC.Symbolics.COM
cc: CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <2810748378-9770893@Kelvin>
Message-ID: <19890128030335.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 25 Jan 89 13:26:18 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> > guess that the most likely route to a solution will involve defining
> > some sort of "tree walk" through the source code, defining the identity
> > of a form as the path taken through the tree to reach that form. I'm
> > guessing that the intuition that the proposal intended to capture is the
> > same thing that this tree walk does.
>
> Yes, that is pretty much what I had in mind, but I agree it is not
> formally stated. Perhaps a more formal statement would be that you do
> a code walk to expand all macros, then do a COPY-TREE on the resulting
> code, then all the LOAD-TIME-VALUE expressions you end up with would have
> the right uniqueness properties.
In other words, the interpreter would be required to do a pre-pass over the
code.
No. This is where the discussion went off the rails. The proposal
already says that interpreters are allowed to multiply evaluate a single
LOAD-TIME-VALUE form. The issue being discussed here is whether interpreters
are required to recognize two LOAD-TIME-VALUE forms as distinct and evaluate
each one separately. A pre-pass is irrelevant to that. For example,
(defmacro load-time-value (form) (list 'quote (eval form))) would be
a valid implementation that always evaluated distinct forms separately.
I just noticed that version 8 directly contradicts itself. It says "in
interpreted code, there is no guarantee as to when evaluation of <form>
will take place" (which I take to mean that it is valid never to
evaluate <form> at all unless a data dependency requires the value of
<form> to be used), but it also says "Implementations must guarantee
that each reference to a LOAD-TIME-VALUE form results in at least one
evaluation of its nested <form>" (which I take to mean that it is
invalid never to evaluate <form> at all).
By the way, although I said that displacing macros never work in Common
Lisp, no one should I imagine that I think displacing LOAD-TIME-VALUE
does not work. LOAD-TIME-VALUE is a special form, not a macro, and
furthermore its action does not depend on the lexical environment.
I prefer to think of the evaluation of LOAD-TIME-VALUE as being similar
to macroexpansion. The only rules for macroexpansion are that a
macroexpansion required by data dependency happens at least once, and
that when COMPILE-FILE is used there aren't any macroexpansions left
over after LOAD time. There is no rule against doing the same
macroexpansion more than once, and there is no rule against caching
macroexpansions.
I don't have time to come up with a precise formulation of the above
idea, but my intuition is that you will find that direction more
fruitful than the direction in version 8 of the proposal, which I think
is trying to constrain the behavior more than is possible within current
Common Lisp implementation techniques.
∂27-Jan-89 1913 CL-Compiler-mailer Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 89 19:13:23 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 528659; Fri 27-Jan-89 22:11:28 EST
Date: Fri, 27 Jan 89 22:12 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: CL-Compiler@SAIL.STANFORD.EDU, Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8901251658.AA20469@defun.utah.edu>
Message-ID: <19890128031202.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 25 Jan 89 09:58:52 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> The part about uninterned symbols is inconsistent. Are they compared by
> name, as it says in one place, or by EQ, as it says in another?
I don't see the inconsistency. If two symbols in a single Common Lisp
"address space" have the same name and are interned in the same home
package, they *must* be EQ, right?
UNinterned symbols. UN, UN, UN. UN.
....My own
feeling is that no valid program ought to have the package environment
defined inconsistently between compile and load time in [deleted] manner,
and we shouldn't waste our time trying to specify what happens if it
is.
I agree, and said so in some other mail sent earlier this evening on
IN-PACKAGE-FUNCTIONALITY.
> I believe it's wrong for structures to be compared by component equality,
> rather than by EQ. It is surely wrong for standard-class instances.
> The LOAD-OBJECTS cleanup proposal can cover this for both structures
> and standard-class instances; two of these are similar as constants
> if they are EQ or if the MAKE-LOAD-FORMS method produces a form
> that produces objects that are EQ. For generic functions and methods,
> the comparison function is EQ and the reconstruction function is
> defined by a MAKE-LOAD-FORMS method essentially coming from the
> metaobject protocol.
I disagree with the idea of changing the handling for structures.
Introducing the LOAD-OBJECTS protocol for standard-class instances is fine,
but structures have been part of the language for a while already and I
don't see any need to change their handling in an incompatible way.
Incompatible? Please point to the place in CLtL that says that similarity
as constants is defined for structures by component equality. For that
matter, point to any place in CLtL that says anything about componentwise
comparison of structures.
In any case, the LOAD-OBJECTS proposal can propose whichever default
behavior for structures the people amending it and voting on it prefer.
> Everything this says about functions strikes me as confused, but I
> haven't thought about it very hard.
It strikes me as confused, too. I've been arguing for simply not requiring
functions to be dumpable at all, but not everybody agrees with me.
I do. Better not to require something that we might understand in the
future, than to require something that we will later discover is screwed
up.
UN. <:-)
∂27-Jan-89 1950 CL-Cleanup-mailer Issue: FUNCTION-NAME (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 89 19:49:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 528674; Fri 27-Jan-89 22:47:46 EST
Date: Fri, 27 Jan 89 22:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: FUNCTION-NAME (Version 1)
To: CL-Cleanup@SAIL.STANFORD.EDU, CL-Compiler@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19890128034814.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Here is the new proposal for the SETF issue that I put up on slides at
the X3J13 meeting. It's been refined a bit, according to the
suggestions various people made.
Assuming this remains in the Cleanup subcommittee, perhaps Larry should
put this on the forthcoming letter ballot so we don't necessarily have
to wait until March to deal with it.
Issue: FUNCTION-NAME
References: SETF rules for what -place- can be (pp.94-7)
FBOUNDP function (p.90)
FMAKUNBOUND function (p.92)
FUNCTION special form (p.87)
SYMBOL-FUNCTION and setf of symbol-function (p.90)
88-002R pages 1-21, 2-21, 2-26, 2-39, 2-44, 2-46, 2-51, and 2-55
(There are additional references for the MEDIUM and LARGE
proposals, but they are not listed here. They're obvious.)
Related issues: SETF-FUNCTION-VS-MACRO, SETF-PLACES (both subsumed by this)
Category: ADDITION
Edit history: Version 1, 23-Jan-89, by Moon
(based on discussion at X3J13 meeting)
Problem description:
The Common Lisp Object System needs a well-defined way to relate the name
and arguments of a writer function to those of a reader function, because
both functions can be generic and can have user-defined methods. The way
that was adopted into Common Lisp when X3J13 voted to accept document
88-002R was to use a list (SETF reader) as the name of the writer function.
Some changes to the non-object-oriented portion of Common Lisp are required
in order to support this.
This issue has three proposals.
Proposal (FUNCTION-NAME:SMALL):
Add a new concept "function-name" (called "function-specifier" in
88-002R). A function-name is either a symbol or a 2-element list whose
first element is the symbol SETF and whose second element is a symbol.
Implementations are free to extend the syntax of function-names to
include lists beginning with additional symbols other than SETF.
Add a new function (FDEFINITION function-name), which returns the
current global function definition named by function-name, or signals
an error if there is no global function definition. This follows all
the same rules listed for SYMBOL-FUNCTION in CLtL p.90.
Add SETF of FDEFINITION to change the current global function definition
named by a function-name. This follows all the same rules listed for
SETF of SYMBOL-FUNCTION in CLtL p.90.
Change the FBOUNDP and FMAKUNBOUND functions, and the FUNCTION special
form, to accept function-names in place of symbols. Implementation
defined extensions to the syntax of function-names cannot use the
symbol LAMBDA, since FUNCTION already uses that symbol.
Change the rules for SETF places (CLtL pp.94-7) by adding the following
clause after all the existing clauses:
- Any other list whose first element is a symbol, call it reader.
In this case, SETF expands into a call to the function named by the
list (SETF reader). The first argument is the new value and the
remaining arguments are the values of the remaining elements of
-place-. This expansion occurs regardless of whether reader or
(SETF reader) is defined as a function locally, globally, or not at
all. For example,
(SETF (reader arg1 arg2...) new-value)
expands into a form with the same effect and value as
(LET ((#:temp-1 arg1) ;force correct order of evaluation
(#:temp-2 arg2)
...
(#:temp-0 new-value))
(FUNCALL (FUNCTION (SETF reader)) #:temp-0 #:temp-1 #:temp-2...)).
Change the functions GET-SETF-METHOD and GET-SETF-METHOD-MULTIPLE-VALUE
to implement the above change to the rules.
Document that a function named (SETF reader) should return its first
argument as its only value, in order to preserve the semantics of SETF.
Change the macro DEFGENERIC and the function ENSURE-GENERIC-FUNCTION to
refer to the function FDEFINITION where they now refer to the function
SYMBOL-FUNCTION.
Change the macros DEFCLASS, DEFGENERIC, and DEFMETHOD, the special forms
GENERIC-FLET and GENERIC-LABELS, and the functions DOCUMENTATION and
ENSURE-GENERIC-FUNCTION to use the term "function-name" where they now
use the term "function-specifier" or "function specifier".
Rationale for FUNCTION-NAME:SMALL:
This is the minimum change to Common Lisp needed to do what 88-002R says
about (SETF reader). Giving implementations freedom to extend the syntax
of function-names allows for current practice. Changing the name from
"function-specifier" to "function-name" avoids confusion and improves
consistency with the rest of the language, at the cost of a few small
changes to 88-002R.
Proposal (FUNCTION-NAME:MEDIUM):
Everything in FUNCTION-NAME:SMALL, and in addition:
Change the DEFUN macro to accept a function-name for its name argument,
instead of only accepting a symbol. If function-name is (SETF sym),
the body is surrounded by an implicit block named sym.
Rationale for FUNCTION-NAME:MEDIUM:
Keeping DEFUN consistent with DEFMETHOD is a good idea. Also 88-002R
says "The name of a generic function, like the name of an ordinary
function, can be either a symbol or a two-element list whose...", which
implies this change to DEFUN.
Proposal (FUNCTION-NAME:LARGE):
Everything in FUNCTION-NAME:MEDIUM, and in addition the following
numbered points, each of which could be adopted independently,
except where explicitly noted:
1. Change the function COMPILE to accept a function-name as its name
argument.
2. Change the function DISASSEMBLE to accept a function-name as its name
argument.
3. Change the FTYPE, INLINE, and NOTINLINE declarations and proclamations
to accept function-names, not just symbols, as function names.
4. Change the FLET and LABELS special forms to accept a function-name in
the name position, not just a symbol.
5. Change the TRACE and UNTRACE macros to accept function-names, not just
symbols, in the function name positions.
6. Change the ED function to accept (ED function-name) in place of
(ED symbol).
7. Change the syntax of a function call to allow a function-name as the
first element of the list, rather than allowing only a symbol.
8. Change the DEFMACRO macro and the MACROLET special form to accept a
function-name in the name position, not just a symbol. Change the
MACRO-FUNCTION function to accept function-names, not just symbols.
Change the last rule for SETF places to use
((SETF reader) #:temp-0 #:temp-1 #:temp-2...)
in place of
(FUNCALL (FUNCTION (SETF reader)) #:temp-0 #:temp-1 #:temp-2...)
so that (SETF reader) can be defined as a macro. This depends on item
7. If item 4 is rejected, MACROLET should be stricken from this item.
9. Add an optional environment argument to FDEFINITION, SETF of
FDEFINITION, FBOUNDP, and FMAKUNBOUND. This is the same as the
&environment argument to a macroexpander. This argument can be used to
access local function definitions, to access function definitions in the
compile-time remote environment, and to modify function definitions in
the compile-time remote environment.
10. Change the second, third, fourth, fifth, seventh, and ninth rules for
SETF places so that they only apply when the function-name refers to the
global function definition, rather than a locally defined function or
macro. (The ninth rule is the one that refers to DEFSETF and
DEFINE-SETF-METHOD; the other rules listed are the ones that list
specific built-in functions). The effect of this change is that SETF
methods defined for global functions are ignored when there is a local
function binding; instead, the function named (SETF reader), which may
have a local function binding, is called. This change is most useful
in connection with item 4, but does not actually depend on it.
11. Clarify that the eighth rule for SETF places (the one for macros)
uses MACROEXPAND-1, not MACROEXPAND.
Rationale for FUNCTION-NAME:LARGE:
This extends the new feature throughout the language, in order to make
things generally more consistent and powerful. Point by point:
1,2,3 - one should be able to compile, examine, and make declarations
about functions regardless of whether they are named with symbols or
with lists.
4 - locally defined non-generic SETF functions are a logical companion
to locally defined generic SETF functions, which can be defined with
GENERIC-FLET or GENERIC-LABELS. They make sense on their own, since one
might define a local reader function and want a local writer function
to go with it.
5,6 - one should be able to apply development tools to functions
regardless of how they are named. The function DOCUMENTATION was already
updated to work for function-names by 88-002R. There might be some
difficulty with implementation-dependent syntax extensions to TRACE and
UNTRACE conflicting with this new syntax.
7 - this restores consistency between the FUNCTION special form and the
first element of a function call form.
8 - it seems more consistent to allow macros to be named the same way
that ordinary functions are named. However, this might be considered
redundant with DEFSETF.
9 - this is not needed by the "chapter 1 and 2" level of CLOS, but might
be used by the metaobject based implementation of ENSURE-GENERIC-FUNCTION.
10 - this change was in SETF-FUNCTION-VS-MACRO and makes item 4 more useful.
11 - this change was in SETF-FUNCTION-VS-MACRO and is a good idea, but
actually is independent of everything else being proposed here.
Examples:
;This is an example of the sort of syntax 88-002R allows
(defmethod (setf child) (new-value (parent some-class))
(setf (slot-value 'child parent) new-value)
(update-dependencies parent)
new-value)
(setf (child foo) bar)
;If SETF of SUBSEQ was not already built into Common Lisp,
;it could have been defined like this, if the MEDIUM or LARGE
;proposal is adopted.
(defun (setf subseq) (new-value sequence start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
;The preceding example would have to be defined like this
;if only the SMALL proposal is adopted. This is a method
;all of whose parameter specializer names are T.
(defmethod (setf subseq) (new-value sequence start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
;Another example, showing a locally defined setf function
(defun frobulate (mumble)
(let ((table (mumble-table mumble)))
(flet ((foo (x)
(gethash x table))
((setf foo) (new x)
(setf (gethash x table) new)))
..
(foo a)
..
(setf (foo a) b))))
;get-setf-method could implement setf functions by calling
;this function when the earlier rules do not apply
(defun get-setf-method-for-setf-function (form)
(let ((new-value (gensym))
(temp-vars (do ((a (cdr form) (cdr a))
(v nil (cons (gensym) v)))
((null a) v))))
(values temp-vars
(cdr form)
(list new-value)
`(funcall #'(setf ,(car form)) ,new-value ,@temp-vars)
`(,(car form) ,@temp-vars))))
Current practice:
No implementation supports exactly what is proposed. Symbolics Genera
and the TI Explorer support something close to the MEDIUM proposal, but
differing in a number of details. Symbolics Genera supports items 1, 2,
3, 6, and 11, and modified forms of items 5 and 8, of the LARGE proposal.
Moon considers this proposal's variations from Symbolics current practice
to be an improvement, although incompatible in some cases.
Many implementations currently support only symbols as function names.
Symbolics Genera and the TI Explorer have some additional function-name
syntaxes.
Cost to Implementors:
The SMALL and MEDIUM proposals are estimated to be no more than 50 lines
of code and require no changes to the "guts" of the interpreter and
compiler. Most of the code for this can be written portably and was
shown on two slides at the X3J13 meeting.
Some of the changes in the LARGE proposal are trivial, some require
the compiler to use EQUAL instead of EQ to compare function names, and
items 4, 7, and 8 might require a more substantial implementation
effort. Even that effort is estimated to be negligible compared to
the effort required to implement CLOS.
Cost to Users:
No cost to users, other than program-understanding programs, since this
is an upward compatible addition.
As with any language extension, some program-understanding programs may
need to be enhanced. A particular issue here is programs that assume
that all function names are symbols. They may use GET to access
properties of a function name or use EQ or EQL (perhaps via MEMBER or
ASSOC) to compare function names for equality. Such programs will need
improvement before they can understand programs that use the new feature,
but otherwise they will still work.
Cost of non-adoption:
We would have to make some other language change since the language
became inconsistent when 88-002R was adopted.
Performance impact:
This has no effect on performance of compiled code. It might slow
down the compiler and interpreter but not by very much.
Benefits:
CLOS will work as designed.
Esthetics:
Some people dislike using anything but symbols to name functions.
Other people would prefer that if the change is to be made at all,
the LARGE proposal be adopted so that the language is uniform in its
treatment of the new extended function names. Other proposals for
how to deal with SETF in CLOS were considerably less esthetic,
especially when package problems are taken into account.
SETF would be more esthetic, but less powerful, if it had only the
proposed setf functions and did not have setf macros. Such a major
incompatible change is of course out of the question; however, if setf
functions are stressed over setf macros, SETF will be much easier to
teach.
Discussion:
Moon supports at least FUNCTION-NAME:MEDIUM. He does not necessarily
approve of all parts of FUNCTION-NAME:LARGE.
∂28-Jan-89 0040 CL-Compiler-mailer re: COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 28 Jan 89 00:39:06 PST
Date: Fri 27 Jan 89 12:24:45-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: re: COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12465956591.25.IIM@ECLA.USC.EDU>
This is an extract from a much longer comment on CLOS Chapter 3. I'm
sending this part to cl-compiler since some people who read that may not
be on CLOS mailing lists.
kab
-----
2. Expansion of the User Interface Macros
In general I have problems with what is specified as occuring at compile-time,
specifically with regard to evaluations which are specified as occuring then.
I'll bring up specific points in discussion of each of the defining macros
individually. It seems to me that to do things in just the way you have
specified, either these macros must side-effect the running system, or you
need EVAL to in some fashion take an environment argument. I don't believe
the former is acceptable, and the latter is a very big change, and not likely
to occur anytime soon.
Also, for each of the defining macros you include the following paragraph.
[Note: Implementations are free to pass additional keyword arguments to
the underlying generic functions provided those keyword argument names are
not in the keyword, lisp, or user packages.]
I think it would be better (and more consistent with recent cleanup proposals)
to change this to say that the additional keywords may not be in the user
package or exported from any package specified by the standard.
2.1. Defclass
You are requiring that the form which creates the initfunction be evaluated
at compile-time. This seems totally inappropriate to me. It must be
arranged that the form which will return the initfunction will be evaluated
in the proper environment at load-time, but this does not require evaluation
at compile-time. The only reason for creating the initfunction at compile-
time is if you are going to call it, and in general that isn't possible, since
it may reference things which won't be around until load-time.
Here is a rough outline of what I would expect the example defclass to expand
into.
`(progn
(eval-when (compile)
(ensure-class 'position
:metaclass (find-class 'standard-class)
:superclasses (list (find-class 'graphics-object t ',<env>))
:direct-slots
(list (make-instance 'standard-direct-slot
:name 'x
:initform '0
:readers '(position-x)
:writers '((setf position-x))
:type 'integer)
...
)
:default-initargs
(list (list ':screen '*position-screen* nil))
:environment ',<env>)
)
(ensure-class 'position
:metaclass (find-class 'standard-class)
:superclasses (list (find-class 'graphics-object))
:direct-slots
(list (make-instance 'standard-direct-slot
:name 'x
:initform '0
:initfunction #'(lambda () 0)
:readers '(position-x)
:writers '((setf position-x))
:type 'integer)
...
)
:default-initargs
(list (list ':screen '*position-screen*
#'(lambda () *position-screen*))))
)
A restriction which may not be immediately obvious to everyone that results
from my view of how this should work is that a class needs to be fully defined
before using it as a :metaclass option to defclass. Basically, metaclasses
should be in a seperate file from the classes which use them, and that file
must be loaded before the using classes can be defined. I don't believe that
this is particularly onerous, since I don't view a metaclass as consisting of
just the class object. It also includes the associated metaobject protocol,
as defined by the set of applicable methods, and these methods can't be
called until they have been 'loaded'.
2.2. Defmethod
Again, you are requiring what I consider inappropriate evaluation at compile-
time. Specifically, I don't believe you should be evaluating the eql
specializer form.
Also, it isn't clear to me that it should be necessary to actually create a
method and call add-method at compile-time. I suppose the information gained
by doing so could be used to sometimes optimize away method lookup at compile-
time. But the inability to properly add eql-specialized methods under some
conditions makes this somewhat dubious to me. It would seem more appropriate
to figure out such things at load-time, possibly by doing things like
transforming method-lookup into an array-access or some such thing. Another
problem with doing such things at compile-time is that it requires that you
be able to do the method combination at compile-time, which would require the
same kinds of restrictions as I've suggested for metaclasses, ie. seperate
compilation of the define-method-combination.
Actually, another point for calling add-method at compile-time is that that
is probably when the lambda-list congruency test is performed. However, that
could be extracted out and done seperately at compile-time.
2.3. Defgeneric
Processing the :method options has the same comments as defmethod above.
2.4. Define-method-combination
TBD
-------
∂28-Jan-89 0858 CL-Compiler-mailer Re: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 28 Jan 89 08:58:09 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA03877; Sat, 28 Jan 89 09:54:46 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA22896; Sat, 28 Jan 89 09:54:28 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901281654.AA22896@defun.utah.edu>
Date: Sat, 28 Jan 89 09:54:26 MST
Subject: Re: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>,
Jon L White <jonl@lucid.com>,
Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>,
Cris Perdue <cperdue@Sun.COM>, CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 27 Jan 89 20:16 EST
> If copying is
> allowed it happens only for objects that the implementation is capable
> of copying without signalling an error or doing anything undefined, and
> without violating "similarity as constants within a single Lisp", a
> concept to be defined by CONSTANT-COMPILABLE-TYPES.
>
> The "similarity as constants within a single Lisp" rule means that
> instances of user-defined STANDARD-CLASS or STRUCTURE-CLASS types
> are never copied. This removes my largest objection to copying.
Hang on here. What's this "similarity as constants within a single
Lisp" business that forbids copying of structures? There seems to be
an unfortunate attempt to drag in the decisions made about how EQUALP
compares STANDARD-CLASS and STRUCTURE-CLASS objects going on here. The
equivalence relationship now defined in issue CONSTANT-COMPILABLE-TYPES
has nothing to do with EQUALP, and if it defines how to construct an
equivalent copy of one of these objects, it ought to be just as
equivalent for COMPILE and EVAL as it is for COMPILE-FILE. Let's not
complicate things further by trying to specify entirely different
rules for the two situations.
-Sandra
-------
∂28-Jan-89 0923 CL-Compiler-mailer Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 28 Jan 89 09:22:53 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA04193; Sat, 28 Jan 89 10:21:06 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA22920; Sat, 28 Jan 89 10:21:01 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901281721.AA22920@defun.utah.edu>
Date: Sat, 28 Jan 89 10:21:00 MST
Subject: Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>,
CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 27 Jan 89 22:12 EST
> UNinterned symbols. UN, UN, UN. UN.
Oops, my oversight -- I must have been asleep. There -is- a rationale
for the apparent inconsistency, which is that -any- two symbols which
are EQ in the source file ought to also be EQ when the compiled file
is loaded. (It was noted that PCL depends on this behavior and some
implementations that didn't behave this way before were "fixed" in
order to accomodate PCL.) I think it would be even more inconsistent
if uninterned symbols behaved differently than interned symbols in
this regard.
> I disagree with the idea of changing the handling for structures.
> Introducing the LOAD-OBJECTS protocol for standard-class instances is fine,
> but structures have been part of the language for a while already and I
> don't see any need to change their handling in an incompatible way.
>
> Incompatible? Please point to the place in CLtL that says that similarity
> as constants is defined for structures by component equality. For that
> matter, point to any place in CLtL that says anything about componentwise
> comparison of structures.
The question here is not comparison of structures, but how
COMPILE-FILE/LOAD produces an equivalent copy of the original
structure. Every Lisp I have ever used dumps them by components.
And, I presume the copier function defined by DEFSTRUCT also copies
structures by components. To me, it not only seems unnecessary to
burden structures with so much extra protocol, it also seems
inconsistent to make the protocol only apply to copying performed by
COMPILE-FILE/LOAD, and not to the default copier function.
-Sandra
-------
∂29-Jan-89 1427 CL-Compiler-mailer issue IN-PACKAGE-FUNCTIONALITY, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 29 Jan 89 14:27:15 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA23771; Sun, 29 Jan 89 15:25:49 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA23505; Sun, 29 Jan 89 15:25:47 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901292225.AA23505@defun.utah.edu>
Date: Sun, 29 Jan 89 15:25:45 MST
Subject: issue IN-PACKAGE-FUNCTIONALITY, version 5
To: cl-compiler@sail.stanford.edu
Here is a message from Moon to cl-cleanup that not all of you may have
seen. It looks like we may have to start a new cl-compiler issue to
deal with what package the loader interns symbols in, split off from
both this issue and issue CONSTANT-COMPILABLE-TYPES.
-Sandra
**** Forwarded Message Follows ****
Date: Fri, 27 Jan 89 21:42 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue IN-PACKAGE-FUNCTIONALITY, version 5
To: Sandra J Loosemore <sandra%defun@cs>
Cc: masinter.pa@xerox.com, cl-cleanup@SAIL.STANFORD.EDU
I fully agree with the first part of this proposal (remove IN-PACKAGE,
add WITHIN-PACKAGE). Like JonL, I disagree with the second part (what
COMPILE-FILE does with symbols). Part of the problem is it uses the
words "interned" and "occupied" which are not given precise definitions.
Here is a suggested recasting of that paragraph of your proposal using
the words defined at the beginning of the chapter:
When a compiled file is loaded, the interned symbols it references
are found by the following procedure. The rules are applied in the
order listed and only the first applicable rule has any effect.
(1) The distinguished empty list symbol NIL retains its identity.
(2) Any symbol accessible at compile time in the package that is the
value of *PACKAGE* is found by calling INTERN at load time with one
argument, the name of the symbol.
(3) A keyword symbol is found by finding or creating a keyword
symbol with the same name.
(4) A symbol that at compile time is an external symbol of its home
package is found at load time by finding the package with the same
name as the compile-time home package, and then finding an exported
symbol of that package with the same name as the compile-time
symbol. If no such package exists, no such symbol exists, or the
symbol is not exported, an error is signalled.
(5) Any other symbol is found by calling INTERN at load time with
two arguments, the name of the symbol and the package with the same
name as the compile-time symbol's home package. If no such package
exists, an error is signalled.
The goal of this procedure is for each symbol reference to be
resolved to the same symbol when a compiled file is loaded as when
the source file is loaded directly with LOAD. It is possible to
create package structures that make that impossible; for example, it
is possible for a symbol to be inaccessible from its own home
package. A conforming program cannot depend on any symbol
resolution behavior that is not provided by the above five rules.
If any top level form in a compiled file changes the value of
*PACKAGE*, other than a WITHIN-PACKAGE appearing as the first
effective top level form in the file, the results are unspecified.
[What I mean by "effective top level form" is to include x in
constructs like (PROGN x ...) and macros that expand into x. Do you
compiler people have a name for this? That is, a WITHIN-PACKAGE
must be the first top level form that has any effect.]
Perhaps this should be a separate proposal from IN-PACKAGE-FUNCTIONALITY?
**** End of Forwarded Message ****
-------
∂29-Jan-89 1428 CL-Compiler-mailer Re: issue IN-PACKAGE-FUNCTIONALITY, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 29 Jan 89 14:28:48 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA23795; Sun, 29 Jan 89 15:27:08 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA23517; Sun, 29 Jan 89 15:27:00 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901292227.AA23517@defun.utah.edu>
Date: Sun, 29 Jan 89 15:26:58 MST
Subject: Re: issue IN-PACKAGE-FUNCTIONALITY, version 5
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>,
cl-cleanup@SAIL.STANFORD.EDU, cl-compiler@sail.stanford.edu
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 27 Jan 89 21:42 EST
Here is some wording that borrows from what you used, that says pretty
much what I intended to say in my original proposal.
When a compiled file is loaded, the interned symbols it references are
found by calling INTERN at load time with two arguments, the name of
the symbol and the package with the same name as the compile-time
symbol's home package. If no such package exists, an error is
signalled.
As far as I can make out, there are two situations where the two
proposals specify different behavior:
(1) The situation where there is a symbol accessible in the
compile-time value of *PACKAGE*, but with another home package. Your
proposal would have the loader INTERN the symbol in the load-time
value of *PACKAGE*, and mine would have it INTERN the symbol in its
compile-time home package. Unless there is an existing symbol with
the appropriate name that is accessible in both packages, the
load-time home package of the resulting symbol would differ under the
two proposals.
(2) The situation where a symbol is external at compile time, but
where there is no such external symbol at load time. Your proposal
would quietly INTERN it as internal symbol in *PACKAGE* if the symbol
were accessible in the compile-time *PACKAGE*, and otherwise signal an
error. Mine would always just quietly INTERN the symbol as internal
in its home package.
The more I think about this, the more I have come to believe that no
conforming program ought to cause either of these two situations to
arise, and that we could just leave the behavior unspecified in these
cases. It's a user interface issue, much like what happens when you
incompatibly redefine a DEFSTRUCT. Or, to give a stronger parallel,
it's like what happens when you load a file that was compiled with
some DEFSTRUCT definitions that are incompatible with the DEFSTRUCT
definitions that happen to be around at load time. (Proposal
COMPILE-ENVIRONMENT-CONSISTENCY says that the behavior is unspecified
in that situation.)
As I understand it, one rationale for the proposal you suggest is that
it makes LOADing compiled files more like LOADing source files, in that
symbols that would be interned in *PACKAGE* when the source file is
loaded ought to also be interned in *PACKAGE* when the compiled file
is loaded, regardless of what the compile-time value of *PACKAGE* was.
Here is an example to explain why I believe that the compile-time
value of *PACKAGE* -does- matter. PCLS has two different packages,
the PSL package and the LISP package, which do not use each other.
Many functions, macros, and special forms with the same names exist in
both packages as distinct symbols with different definitions. If I
have a file that really wants to use the Common Lisp definitions,
rather than the PSL definitions, the symbols from LISP package -must-
be accessible at compile time in order for the compiler to apply the
right set of macro expansions and use the right set of special form
compilers. If the compile-time *PACKAGE* is such that the PSL package
macros get used instead, then the compiled file would end up
referencing functions that don't even exist in the LISP package, and
under your proposal you'd lose no matter what the load-time value of
*PACKAGE* is. This is why PCLS ended up including an explicit package
prefix on all symbols in compiled files. The same considerations
apply equally well when talking about user-defined macros and all the
other kinds of things that the compiler is allowed to "wire in" to the
code it compiles.
Basically, what I would like to do is come up with a unified proposal
that is compatible with both of the existing ones where they agree,
and leave what happens in the situations where they disagree to be
explicitly vague. In other words, it would place some additional
COMPILE-FILE/LOAD consistency requirements on conforming programs --
something along the lines of saying that the compile-time value of
*PACKAGE* must be the same as the load-time value, any symbols
referenced in the compiled file that are accessible in *PACKAGE* but
with another home package at compile-time must also be accessible in
both packages at load-time, etc. (I'll obviously have to think about
this some more to get all the details right.)
Do you approve of this general direction?
-Sandra
-------
∂30-Jan-89 0720 CL-Cleanup-mailer Issue: FUNCTION-NAME (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 30 Jan 89 07:20:34 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 529874; Mon 30-Jan-89 10:18:34 EST
Date: Mon, 30 Jan 89 10:18 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: FUNCTION-NAME (Version 1)
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CL-Cleanup@SAIL.STANFORD.EDU, CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19890128034814.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <890130101826.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
I'm still thinking about this, but while I am I wanted point out that
MEDIUM is unacceptable to me because I don't think FLET and DEFUN should
disagree on what they permit as defined names. If FLET were added to
MEDIUM, I suspect I'd think it was an internally consistent position.
LARGE has an appeal to me in general, but I'm still mulling over
the specifics.
I'll reply in more detail later.
∂30-Jan-89 0737 CL-Compiler-mailer Re: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 30 Jan 89 07:36:12 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa01422; 30 Jan 89 13:18 GMT
Date: Sun, 29 Jan 89 21:32:53 GMT
Message-Id: <28201.8901292132@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue: QUOTE-SEMANTICS, or QUOTE-MAY-COPY (Version 4)
To: Jon L White <jonl%lucid.com@NSS.Cs.Ucl.AC.UK>, KMP@scrc-stony-brook.arpa
Cc: Moon@scrc-stony-brook.arpa, CL-Compiler@sail.stanford.edu
> re: The problem is that a lot of copying advocates have been going around
> trying to use "the need for copying" as leverage for restricting
> the set of things which I may quote. My view is that it is my write
> to quote whatever I want, and it's up to the person who thinks they
> can do something fun with copying to not get themselves in deeper than
> they can handle.
>
> Kent, I agree with you 100% on this (your "point 2"; modulo typos,
> of course). It looks like you and I may be in agreement about this
> whole issue.
I would agree too. My only quibble is that it's not just "the need
for copying" that's used a lever. "Consistency with file compilation"
is also being used as a lever.
∂30-Jan-89 1003 Common-Lisp-Object-System-mailer Issue: FUNCTION-NAME (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 30 Jan 89 10:03:07 PST
Received: from Semillon.ms by ArpaGateway.ms ; 30 JAN 89 10:00:38 PST
Date: Mon, 30 Jan 89 10:00 PST
From: Gregor.pa@Xerox.COM
Subject: Issue: FUNCTION-NAME (Version 1)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: CL-Cleanup@SAIL.STANFORD.EDU, CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Object-System@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-5.text.newest
In-Reply-To: <19890128034814.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890130180031.2.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
I support FUNCTION-NAME:MEDIUM and may support LARGE once I think about
it some more.
As I explained in Hawaii, support for either of these is based on the
:conc-name bugs being removed from the condition system. Of course, I
believe the best way to do that is to CLOSify it.
-------
∂30-Jan-89 1241 CL-Compiler-mailer Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 30 Jan 89 12:41:20 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA11678; Mon, 30 Jan 89 12:42:09 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA09400; Mon, 30 Jan 89 12:38:51 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA11122; Mon, 30 Jan 89 12:41:42 PST
Date: Mon, 30 Jan 89 12:41:42 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8901302041.AA11122@clam.sun.com>
To: cl-compiler@sail.stanford.edu, moon@stony-brook.scrc.symbolics.com
Subject: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
David Moon had a number of valuable comments on version 5. This note
is to respond to them each in turn.
> I think this suffers from fundamental confusion between three distinct
> concepts:
> (1) relation of objects in the input of COMPILE-FILE to corresponding
> objects in the result of LOAD of the output of COMPILE-FILE.
> (2) relation of two objects in the output of a single COMPILE-FILE.
> (3) relation of two objects in the output of two different COMPILE-FILEs.
> All of these are important, but the answers are different. I think they
> all have to be dealt with within one proposal, but the writeup for each
> datatype should be conscious of each of the three issues.
It is my desire to specify compiled constants using only the concept
of objects in the source code and objects resulting from COMPILE-FILE
followed by LOAD. I have already modified the statement of parts of
the proposal to come closer to this goal. In my opinion it would just
make the spec too much more complicated to introduce the notion of
"objects in the output" of a COMPILE-FILE or COMPILE-FILEs. For those
who believe such concepts are necessary, how about waiting until
Version 6 appears before trying demonstrate that?
On cross-compilers: I think it is necessary to define "similarity as
constants" across address spaces as well as within a single address
space. Note that rational numbers can be compared across address
spaces based on comparing the mathematical values represented, and the
same applies to truth and falsity. I believe that the same can be
made to work for characters. Similarity of aggregates of numbers and
characters can be specified in terms of similarity of their
componenents. The spec attempts to define similarity of packages and
symbols basically in terms of comparison of strings also.
On uninterned symbols: They are compared both by name *and* by EQ,
but we have to avoid saying that two uninterned symbols must be EQ to
be similar as constants, because this does not work across address
spaces. At the same time if, say, a source code constant contains the
same uninterned symbol in two places, the resulting constant must
contain an uninterned symbol of the same name in the same two places.
Interned symbols: I've been trying to avoid splitting issues out
because it makes extra work for me, but I think handling of interned
symbols will have to be split out. Personally I like the direction
proposed by Sandra. I believe that binding a symbol name to symbols
in different packages at compiletime versus runtime has a lot more
potential for getting programmers into trouble than for solving their
problems. (Note for example that inline functions are liable to be
bound at compiletime in any case.)
ARRAY-ELEMENT-TYPE: I am correcting the proposal to require element
types to be "EQUAL-TYPEP" (the function David mentions as missing from
Common Lisp).
Adjustable arrays: Since the discussion of adjustable and simple
arrays at the January X3J13 meetings, I understand David's point, and
have modified this part of the proposal.
Structures: Yes, similarity of structures must be revisited. David's
suggestions look entirely plausible.
Hash tables: There is a relationship with EQUALP, as suggested.
Readtables: Everyone seems to realize that there is a problem due to
functions in readtables. If a readtable contains only symbols
representing functions rather than function objects, it could be
considered dumpable. On the other hand, if I don't hear any support
for supporting readtables, readtables will be dropped from Version 6.
Functions: Yes, the statements about functions don't hack it. At this
point compiled functions are not to be supported in compiled
constants. I guess functions will not be supported at all in compiled
constants unless someone else works to make it so.
∂30-Jan-89 1304 CL-Compiler-mailer Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 30 Jan 89 13:04:12 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 530176; Mon 30-Jan-89 16:01:55 EST
Date: Mon, 30 Jan 89 16:01 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
To: cperdue@Sun.COM
cc: cl-compiler@sail.stanford.edu, moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8901302041.AA11122@clam.sun.com>
Message-ID: <890130160146.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Mon, 30 Jan 89 12:41:42 PST
From: cperdue@Sun.COM (Cris Perdue)
...
On cross-compilers:
...
I do not believe you can write a cross-compiler for Lisp which works in
the general case.
You can get caught in situations where a particular macro definition must
expand code for the current environment, for the target environment,
for other macros which must run in the current environment to produce
output for the target, for other macros which must run in the current
environment to produce output which must run in the current environment
and which must produce output for the target, and so on.
The root of the problem is that you are permitted to use a macro definition
in the same file in which the macro is defined. I also believe that, good
or bad, it's too late to change this property of the language.
I believe that you can write a cross-compiler for a subset of Common Lisp,
but I think it would be somewhat difficult to describe the restrictions on
that subset to the casual user. Anyway, once you start to restrict yourself
to subsets, the whole ballgame becomes a lot easier and not really very
interesting, since you can always define away any problem situation that
might come up in the full language.
As such, I believe any time spent discussing cross-compilers is time wasted.
If someone really claims to support a cross-compiler, I'd be interested to
hear the concept defended.
∂30-Jan-89 1826 CL-Cleanup-mailer issue IN-PACKAGE-FUNCTIONALITY, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 30 Jan 89 18:26:34 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA07555; Mon, 30 Jan 89 19:24:53 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA25846; Mon, 30 Jan 89 19:24:50 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901310224.AA25846@defun.utah.edu>
Date: Mon, 30 Jan 89 19:24:48 MST
Subject: issue IN-PACKAGE-FUNCTIONALITY, version 6
To: cl-cleanup@sail.stanford.edu
Cc: cl-compiler@sail.stanford.edu
Here is a new version of the writeup on this issue which incorporates
all of the suggestions I've received so far. In particular, all of the
parts dealing with compile/load package consistency requirements have
been split off to a new cl-compiler issue, COMPILE-FILE-SYMBOL-HANDLING
(I'm working on a draft writeup). And, the name of the macro has been
changed to SELECT-PACKAGE.
Issue: IN-PACKAGE-FUNCTIONALITY
References: IN-PACKAGE (p182-183)
Category: CHANGE
Edit history: 07-Jul-88, Version 1 by Pitman
7-Oct-88, Version 2 by Masinter (discussion)
8-Dec-88, Version 3 by Masinter
12-Dec-88, Version 4 by Masinter
20-Jan-89, Version 5 by Loosemore
30-Jan-89, Version 6 by Loosemore
Related-Issues: DEFPACKAGE (passed)
COMPILE-FILE-SYMBOL-HANDLING
Problem Description:
There are two typical uses for IN-PACKAGE -- to define/create a package
and to select a package. The fact that these two purposes have been
given to the same function has led to reduced error checking.
A more general problem is that the "Put In Seven Extremely Randoms"
convention described in CLtL is now recognized by many people as being
unsatisfactory for both package definition and package selection.
The DEFPACKAGE macro provides a much cleaner mechanism for package
definition, but there is still a need for a convenient way to select
a package that has well-defined compilation semantics.
Proposal (IN-PACKAGE-FUNCTIONALITY:NEW-MACRO):
Add a new macro:
SELECT-PACKAGE name [macro]
This macro causes *PACKAGE* to be set to the package named NAME,
which must be a symbol or string. An error is signalled if the
package does not already exist. Everything this macro does is also
performed at compile time if the call appears at top-level.
Remove the function IN-PACKAGE from the standard.
Remove the second paragraph of section 11.7 in CLtL. (This includes
the requirement for special compile-time treatment of the various
package functions.)
Rationale:
This could allow improved error checking and modularity, with only
minimal loss of functionality.
The rationale for proposing SELECT-PACKAGE as a replacement for
IN-PACKAGE, rather than simply changing IN-PACKAGE to have this
behavior, is that such an incompatible change would be confusing to
many people, and would make it more difficult to detect obsolete
usages. There is nothing in this proposal that would prevent
implementations from continuing to provide IN-PACKAGE as an extension.
Making SELECT-PACKAGE a macro rather than a function means that there
is no need to require COMPILE-FILE to handle it specially. Since
DEFPACKAGE is also defined to side-effect the compilation environment,
there is no need to require any of the package functions to be treated
specially by the compiler.
The language in section 11.7 of CLtL puts the burden on
implementations of ensuring that all symbols in a file which is
compiled and loaded end up in the same package that they would if the
source file were loaded interpretively. No implementation can
possibly meet this requirement because, in general, the runtime
behavior of the program cannot be predicted by the compiler.
Current Practice:
Probably no one implements this behavior exactly since it's an
incompatible change to CLtL.
Cost to Implementors:
The SELECT-PACKAGE macro can be implemented trivially by using
EVAL-WHEN in its expansion:
(defmacro within-package (name)
`(eval-when (eval compile load)
(setq *package*
(or (find-package ',name)
(error "Package ~s does not exist." ',name)))))
The changes required to COMPILE-FILE to remove the magic treatment
of the package functions are also likely to be small.
Cost to Users:
In most cases, minor syntactic changes to some files would be
necessary. Programmers that are now using the "Put In Seven
Extremely Randoms" convention will probably find it straightforward
to convert their code to do a DEFPACKAGE followed by a
SELECT-PACKAGE.
Cost of Non-Adoption:
The specification of COMPILE-FILE will be much more difficult to
understand.
The standard will require compilers to solve the halting problem.
Benefits:
Modular package declarations would be encouraged and errors due
to demand-creation of packages would be easier to detect.
The specification of COMPILE-FILE will be simplified.
There will be a clear statement of the requirements for program
conformance, as relating to usage of packages.
Aesthetics:
The fact that IN-PACKAGE is currently ambiguous about intent (whether
the package should exist already or not) is clearly not aesthetic.
Removing it can't be any worse.
The fact that the currently stated requirements for handling of
the package functions by the compiler are not implementable is
clearly not aesthetic.
Proposal (IN-PACKAGE-FUNCTIONALITY:SELECT-ONLY):
Eliminate the ability of IN-PACKAGE to create a package on demand.
Eliminate the :NICKNAMES and :USE arguments to IN-PACKAGE, since they
are no longer needed.
The results of calling IN-PACKAGE if the package does not already
exist are implementation dependent; implementations "should signal"
an error, or otherwise provide the user with a way to recover from
the situation.
Examples:
#1: (IN-PACKAGE 'NO-SUCH-PACKAGE) ;would signal an error
#2: (DEFPACKAGE FOO ...options...) ;defines/creates a package
(IN-PACKAGE 'FOO) ;selects an existing package
Rationale:
This could allow improved error checking and modularity, with only
minimal loss of functionality.
Current Practice:
Probably no one implements this behavior since it's in direct
contradiction of both the definitions and numerous examples in CLtL.
Cost to Implementors:
As written, no change to implementations is required, but many will
want to make IN-PACKAGE signal an error. This change would be
straightforward to implement. The cost may not be trivial in all
cases, but should not be very large.
Cost to Users:
In most cases, minor syntactic changes to some files would be
necessary.
In some cases, no changes would be necessary since files may
already be doing IN-PACKAGE in situations where the author is
hoping he's made sure the real package declaration is already
loaded.
Cost of Non-Adoption:
Reduced error checking.
Less modular code.
Benefits:
Errors due to demand-creation of a package by IN-PACKAGE without
appropriate uses of the :USE or :NICKNAMES or without appropriate
calls to EXPORT, etc. afterward would be easier to detect.
Modular package declarations would be encouraged.
Aesthetics:
The fact that IN-PACKAGE is currently ambiguous about intent (whether
the package should exist already or not) is clearly not aesthetic.
Some people feel this change would be an aesthetic improvement.
Others feel that an incompatible change to IN-PACKAGE would merely
be confusing.
Discussion:
The dual use of IN-PACKAGE has not been helpful and is confusing.
Both proposals represent an incompatible change to the language as
described in CLtL and will break any program that uses the "Put In
Seven Extremely Randoms" convention described in section 11.9.
Some people may find proposal NEW-MACRO more palatable if it merely
deprecated IN-PACKAGE, instead of removing it entirely.
Loosemore and Moon support proposal IN-PACKAGE-FUNCTIONALITY:NEW-MACRO.
-------
∂31-Jan-89 0154 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 31 Jan 89 01:54:38 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA03975g; Tue, 31 Jan 89 01:49:36 PST
Received: by bhopal id AA14634g; Tue, 31 Jan 89 01:51:53 PST
Date: Tue, 31 Jan 89 01:51:53 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901310951.AA14634@bhopal>
To: jlm@lucid.com
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Jim McDonald's message of Thu, 26 Jan 89 12:16:11 PST <8901262016.AA10651@pitney-bowes>
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 4
re: (A) Jonl may correct me, but I think the experience at Lucid has
been that the overhead per constant for detecting circularities
is minor, perhaps down in the noise.
What you say is generally true, but of course there is at least one painful
counterexample that can legitimately come up -- FASDMP.
Normally, file compilation spends its time in things like file-io,
macroexpansion, source-code analysis, code-generation, etc; so that the
hash-tabling time to EQify data (and to stop circularities) is down in
the noise. [Well, that's assuming that the implementation in question has
a reasonably efficient version of "hashing" hash-tables, rather than merely
random "tables" that happen to be called hash-tables -- at the recent X3J13
meeting, a of couple people who really ought to have known better claimed
they didn't understand at all what that means.]
But for FASDMP, one can construct an arbitrarily bad case: no time
spent in macroexpansion, code analysis or generation, and practically
no time spent in file-io; and no sharing or circularity whatsoever in
the datastructures. Thus *all* the time spent in the table-look-up
routines (read: "hash" routines) is wasted. Still, this is such a
special case that I can't see devoting time trying to optimize it
unless more than one weirded-out user falls upon it as follows:
(1) It is a natural case of some money-earning software product, and
not just another exercise to show how bad someone's compiler is;
(2) The time saved by a special-case switch to turn off the tabling
algorithms can be translated into a real dollars-and-cents profit
for that company -- i.e., not just "frequently is 3% slower", or
"runs 300% slower once in the lifetime of the company".
re: I think any serious implementation of COMPILE-FILE will quietly handle
circular data, just as any serious garbage collector is expected to.
Well-said, Jim!
-- JonL --
∂31-Jan-89 0511 CL-Compiler-mailer Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 31 Jan 89 05:11:10 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04013g; Tue, 31 Jan 89 05:03:37 PST
Received: by bhopal id AA14974g; Tue, 31 Jan 89 05:05:58 PST
Date: Tue, 31 Jan 89 05:05:58 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901311305.AA14974@bhopal>
To: sandra%defun@cs.utah.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Sandra J Loosemore's message of Wed, 25 Jan 89 09:58:52 MST <8901251658.AA20469@defun.utah.edu>
Subject: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
re: This could cause some interesting problems if the value of *PACKAGE*
changes throughout the file. Note that neither CLtL nor my revised
proposal on issue IN-PACKAGE-FUNCTIONALITY forbid this from happening.
(CLtL merely -suggests- putting the call to IN-PACKAGE at the top of
the file, "as a matter of style"). Suppose that at compile-time,
symbol BAR is accessible in both packages P1 and P2 (but its home
package is somewhere else), and at load-time it's not.
(in-package :p1)
... 'bar ...
(in-package :p2)
... 'bar ...
Would the correct load-time behavior for this example be to create two
different, non-EQ symbols named BAR, one in each of packages P1 and P2?
Obviously, the correct load-time behaviour cannot do anything which fails
to preserve EQness on these symbol references (your statement of the problem
was that both tokens 'bar above, in the source file, access only one symbol).
However, since you said with malice aforethought that the necessary
package interrelations are different at load time than at compile time,
then in some sense we can reply with "the results are undefined".
I intend to reply more fully to moon's "amendment" to your
IN-PACKAGE-FUNCTIONALITY proposal; and in that reply, I will detail
why it is the case that compiling out symbols should *not* be
specified to be any of the following three simple algorithms:
(1) fully-package qualified
(2) just like PRINT
(3) moon's minor variation on PRINT
That response will make it more clear why having two IN-PACKAGEs in a
single file ought to be allowable (although the Lucid documentation
warns against it for reasons of style). Anyone on this mailing list who
doesn't receive cl-cleanup mail, but who would like to see this reply,
should ask me privately for a copy. The essense of this reply will
be that it is useful for an implementation to allow as many gratuitous
variations in the package setup between compile-time and load-time
readings, provided that the source file does the same thing in each
variation.
re: I disagree with the idea of changing the handling for structures.
Introducing the LOAD-OBJECTS protocol for standard-class instances is fine,
but structures have been part of the language for a while already and I
don't see any need to change their handling in an incompatible way. If
people find that the default handling of structures is not sufficient for
their needs, that's probably a sign that they really need to use the more
complex protocol for standard-class objects instead.
I very much agree with what you say here. Unfortunately, not enough
people objected at the right time -- when the vote on 88-002R was being
taken -- and this "trojan horse" sneaked in to destroy the defstruct
house. [in fact, I wonder how many people actualy read 88-002R before
voting on it?] It's possible that changing the default defstructs to be
CLOS instances will make it smoother for PCL transition; but I don't see
how the incompatible changes to the :PRINT-FUNCTION, :COPIER, and
EQUALP treatment on defstructs helps anyone.
Date: Fri, 27 Jan 89 22:12 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
In-Reply-To: <8901251658.AA20469@defun.utah.edu>
. . .
Incompatible? Please point to the place in CLtL that says that similarity
as constants is defined for structures by component equality. For that
matter, point to any place in CLtL that says anything about componentwise
comparison of structures.
See CLtL, p.81, second paragraph of the definition of EQUALP. In the
context of 1984 CL, the phrase "objects which have components" clearly
includes defstruct instances. It even explicitly mentions that you
can lose due to circularity, and that that's just too bad if you do.
By way of contrast, when defstruct instances were to be excluded from
EQUAL, the phraseology used was "Certain objects that have components ..."
(see p.80), and then an explicit listing of those "Certain objects"
followed; the implication is clear that any type not directly mentioned
in that list is not to be descended by EQUAL.
Thus EQUALP was intended to descend anything that had (pointer)
components -- the only exception being symbols, which is explicitly
listed at the bottom of p.81 [I think it would have been acceptable
to define symbols as not having "components"; but since that would
surely raise fruitless arguments with numerous persons, it was better
to make an explicit exception for symbols.]
Unfortunately, the EQUAL-STRUCTURE amendment that passed at the Hawaii
meeting retracted this very useful action of EQUALP on defstructs, and
rendered it useless again. Hopefully, the final version of the LOAD-
OBJECTS proposal will specify a more useful default behaviour (e.g.,
"just like the old CLtL behaviour"?), but note it this will have to
amend the already-passed EQUAL-STRUCTURE proposal.
-- JonL --
∂31-Jan-89 0527 CL-Compiler-mailer Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 31 Jan 89 05:27:21 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04022g; Tue, 31 Jan 89 05:21:38 PST
Received: by bhopal id AA15007g; Tue, 31 Jan 89 05:23:50 PST
Date: Tue, 31 Jan 89 05:23:50 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8901311323.AA15007@bhopal>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Cc: Gray@DSG.CSC.TI.COM, KMP@STONY-BROOK.SCRC.Symbolics.COM,
Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: Kent M Pitman's message of Thu, 26 Jan 89 08:54 EST <890126085447.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-TIME-EVAL, Sub-Issue: Displacing macros
re: Personally, I can't imagine how displacing macros can work at all.
Previous mail may have suggested that MacLisp's interpreter used
"displacing macros". This was not a part of the interpreter; rather, it
was a common idiom of code produced by the DEFMACRO macro. Furthermore,
it was not the only option, nor was it the default (as I remember it).
In fact, years ago I would frequently make "pure" dumps of a MacLisp
system with lots of intrepreted code stored in it, in read-only areas
(I got it there by calling PURCOPY on the definition of each interpreted
function). The macro cache feature I selected for this application was
called MACROMEMO (it worked like Interlisp's CLISPARRAY).
re: But this whole sub-issue aside, all we're really saying is that
LOAD-TIME-VALUE should not be done by displacing.
Right!
-- JonL --
∂31-Jan-89 1226 CL-Editorial-mailer Re: Issue: EXTENSIONS-POSITION (version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 31 Jan 89 12:26:17 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 31 JAN 89 11:20:40 PST
Date: 31 Jan 89 11:18 PST
From: masinter.pa@Xerox.COM
Subject: Re: Issue: EXTENSIONS-POSITION (version 1)
In-reply-to: your message of 10 Jan 89 14:30
To: chapman%aitg.DEC@decwrl.dec.com
cc: cl-editorial@sail.stanford.edu, cl-compiler@sail.stanford.edu
Message-ID: <890131-112040-8084@Xerox>
The compiler issue SHARP-COMMA-CONFUSION seems to imply that
implementations "could continue to provide #, as an extension". However, is
such an extension legal? Can't legal common lisp programs redefine #, if #,
isn't in the language? If they can, wouldn't it disallow having #, be an
extension?
I'm discussing this under EXTENSIONS-POSITION since the proposal itself for
#, didn't propose making it explicit in the standard that #, "was allowed
as an extension".
∂31-Jan-89 1237 CL-Editorial-mailer Re: Issue: EXTENSIONS-POSITION (version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 31 Jan 89 12:37:20 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 530994; Tue 31-Jan-89 15:34:56 EST
Date: Tue, 31 Jan 89 15:34 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: EXTENSIONS-POSITION (version 1)
To: masinter.pa@Xerox.COM
cc: chapman%aitg.DEC@decwrl.dec.com, cl-editorial@sail.stanford.edu,
cl-compiler@sail.stanford.edu
In-Reply-To: <890131-112040-8084@Xerox>
Message-ID: <890131153443.1.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: 31 Jan 89 11:18 PST
From: masinter.pa@Xerox.COM
The compiler issue SHARP-COMMA-CONFUSION seems to imply that
implementations "could continue to provide #, as an extension". However, is
such an extension legal? Can't legal common lisp programs redefine #, if #,
isn't in the language? If they can, wouldn't it disallow having #, be an
extension?
Presumably the only thing that defining it as an extension can mean from
CL's point of view is `initially definining' it as an extension. Whether
an implementation permits you to redefine its extensions is between that
implementation and its users and beyond the scope of Common Lisp. For
example, it is common practice to redefine some kinds of system functions
in Genera -- to extend the system in interesting ways, to fix bugs, etc.
Given this, I don't see that there is necessarily a conflict.
I'm discussing this under EXTENSIONS-POSITION since the proposal itself for
#, didn't propose making it explicit in the standard that #, "was allowed
as an extension".
∂31-Jan-89 1248 CL-Compiler-mailer Re: Issue: EXTENSIONS-POSITION (version 1)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 31 Jan 89 12:48:45 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA29248; Tue, 31 Jan 89 13:45:45 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA26447; Tue, 31 Jan 89 13:45:42 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8901312045.AA26447@defun.utah.edu>
Date: Tue, 31 Jan 89 13:45:40 MST
Subject: Re: Issue: EXTENSIONS-POSITION (version 1)
To: masinter.pa@Xerox.COM
Cc: chapman%aitg.DEC@decwrl.dec.com, cl-editorial@sail.stanford.edu,
cl-compiler@sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM, 31 Jan 89 11:18 PST
CLtL p. 351 indicates that more # read macros could be added to the
standard language, but doesn't really address the issue of whether
implementations can provide their own # read macros. It does list a
set that are explicitly reserved for users, though.
I know of at least one implementation (Lucid) that has added a #P
syntax for pathnames -- see the requirement on p. 370 that pathnames
PRINT in such a way that they can be READ in again.
-Sandra
-------
∂31-Jan-89 1300 CL-Editorial-mailer Re: Issue: EXTENSIONS-POSITION (version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 31 Jan 89 13:00:27 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 531021; Tue 31-Jan-89 15:57:23 EST
Date: Tue, 31 Jan 89 15:57 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: EXTENSIONS-POSITION (version 1)
To: sandra%defun@cs.utah.edu
cc: masinter.pa@Xerox.COM, chapman%aitg.DEC@decwrl.dec.com,
cl-editorial@sail.stanford.edu, cl-compiler@sail.stanford.edu
In-Reply-To: <8901312045.AA26447@defun.utah.edu>
Message-ID: <890131155704.3.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Tue, 31 Jan 89 13:45:40 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
... It does list a set that are explicitly reserved for users, though. ...
In the world of third- (or Nth-) party products, I have to say that I
find this concept pretty bizarre. If I market two Common Lisps, one
layered atop the other, or if I market a Lisp and a Lisp+Tools (eg,
embedded expert system) environment, is the layered product a "user"? If
I think I'm a user for months until I realize I've got something
valuable and then decide to sell it, must I go through and eliminate my
use of readmacros because suddenly I'm not the end user?
I think we should eliminate the seemingly arbitrary distinction between
Nth level and N-1th level users. CL either defines something or it does
not. What happens after that is out of its jurisdiction. We don't define
the myriad of other things that might be added later; of what possible
value is it for us to reserve a few obscure characters in an obscure
namespace?
As an aside, if we did readtables right (allowed local binding of them)
we could forbid extension and say that extensions should be provided in
another readtable.
∂31-Jan-89 1638 CL-Compiler-mailer Issue: MACRO-CACHING (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 31 Jan 89 16:38:05 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 531237; Tue 31-Jan-89 19:36:02 EST
Date: Tue, 31 Jan 89 19:35 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: MACRO-CACHING (Version 1)
To: CL-Compiler@SAIL.Stanford.EDU
Message-ID: <890131193546.7.KMP@BOBOLINK.SCRC.Symbolics.COM>
Even if nothing ever comes of this proposal, at least the presence of
the issue name will give us a place to file any flaming on this topic so
that it doesn't have to get us side-tracked when we're really supposed
to be discussing some other issue...
-----
Issue: MACRO-CACHING
Forum: Compiler
References: 8.2 Macro Expansion (CLtL pp151-152),
Issues PACKAGE-CLUTTER, LISP-SYMBOL-REDEFINITION,
QUOTE-SEMANTICS (a.k.a. QUOTE-MAY-COPY),
and MACRO-ENVIRONMENT-EXTENT
Category: Clarification
Edit history: 31-Jan-89, Version 1 by Pitman
Status: For Internal Discussion
Background:
CLtL suggests that macro caching is a legitimate strategy.
Two particular kinds of caching are common:
Displacement. A macro expansion function displaces the actual macro in
order to avoid any later need for lookup.
Table. A macro expression is looked up in a cache (such as a hash table)
to avoid having to run the expander code.
While CLtL seems to expressly suggest these strategies to be legitimate,
linguistic constraints show that in most cases they are not. The problems
are things like:
- lexical scoping (MACROLET and SYMBOL-MACROLET, and FLET and LET to
the extent that they shadow the effect of MACROLET and SYMBOL-MACROLET,
respectively).
- ``read only'' structure
To see the problem, consider the following examples:
(SETQ FOO1 '(FOO))
(EVAL `(LIST (MACROLET ((FOO (&WHOLE FORM) '(+ 1 1))) ,FOO1)
(MACROLET ((FOO (&WHOLE FORM) '(+ 1 2))) ,FOO1)))
=> (2 3)
Note that because the lexical contour may vary for an EQL expression,
however, displacing the expansion will cause confusion:
(DEFUN DISPLACE (X Y)
(SETF (CAR X) (CAR Y))
(SETF (CDR X) (CDR Y))
X)
(DEFVAR FOO2 '(FOO))
(EVAL `(LIST (MACROLET ((FOO (&WHOLE FORM)
(DISPLACE FORM '(+ 1 1)))) ,FOO2)
(MACROLET ((FOO (&WHOLE FORM)
(DISPLACE FORM '(+ 1 2)))) ,FOO2)))
=> (2 2)
CLtL suggests that a displacement hook might be placed in
*MACROEXPANSION-HOOK*. The above example shows that to be an
unreliable technique.
If this were not enough, displacement is also inappropriate because
no Common Lisp primitive can tell the difference between regular list
structure and read-only list structure. Since a macro form being
expanded might have been read-only in some implementations (e.g., EVAL
of a quoted list), the macro cannot reliably side-effect the structure.
In the case of table-lookup, the problem is more complicated.
Table-lookup does not have a necessary effect beyond the particular
lookup being done at the moment. To do table-lookup correctly relies
on the key being not only the expression but also the lexical
environment object. Whether the cost of making and throwing away so
many tables was worth the savings over running the macro expander is
not at all clear. And the GC effects of caching every macro environment
ever seen may be extraordinary, however correctness could in principle
be preserved by doing such a two-dimensional lookup... at least unless
we decide that macro environments have only dynamic extent. [A separate
proposal, MACRO-ENVIRONMENT-EXTENT, addresses this issue. If it passed,
then there would really be no way for users to do reliable macro caching
without cooperation from the system to have the cache be part of the
environment itself.]
Problem Description:
Macro caching by displacement is provably not semantically valid.
Macro caching by table lookup is difficult for a user to do correctly,
and in any case is not possible to handle efficiently in user code.
Proposal (MACRO-CACHING:DISALLOW):
1. a. Clarify that macro caching by displacement is not semantically
valid in user code.
b. Clarify that macro caching by displacement is semantically valid
for system macros and special forms, provided that such caching
does not prejudice the expansion of user-code contained in any
displaced code. For example:
(PROG () (FOO))
could displace to a BLOCK, but the (FOO) must appear un-expanded
in the BLOCK in case the BLOCK occurs in more than one lexical
environment.
2. a. Clarify that macro caching by table lookup is not semantically
valid in user code in order to correctly respect the lexical
environment.
Implementations are free to extend the language to permit such
lookup and to offer functions which support it in a more efficient
way, but code using such functions would, of course, not be portable.
b. Clarify that macro caching by table lookup is valid for the system,
but only if it correctly respects the lexical environment.
Proposal (MACRO-CACHING:RESTRICT):
Like DISALLOW, but change 2a to:
Clarify that macro caching by table lookup is semantically valid only
if the lookup is keyed both on the form and the environment.
Implementations are free to extend the language to offer functions
which support it in a more efficient way, but code using such functions
would, of course, not be portable.
Rationale:
1. a. Displacement has effects which by their nature transcend
lexical boundaries.
b. The system can assure that lexical boundaries are irrelevant in some
cases because users are not permitted to redefine or shadow definitions
in the initial LISP system. [See issues PACKAGE-CLUTTER and
LISP-SYMBOL-REDEFINITION.]
2. a. Users can only associate an environment with a macro cache table
in a very clumsy way. Also, Permitting them to do so at all forces
macro environments to have indefinite extent, and works against
efficiency in compilers.
b. The system is capable of allocating space in an environment object
for a macro cache which can be reliably kept up in synch with the
lexical environment environment.
Test Case:
;; #1: File compiling this definition in some implementations will produce
;; a definition that returns read-only list structure. The call to EVAL
;; on the result must not try to modify the read-only structure during
;; macroexpansion. [See issue QUOTE-SEMANTICS.]
(DEFUN READ-ONLY-FOO () '(MACROLET ((FOO (&WHOLE FORM) (+ 1 1))) (FOO)))
(EVAL (READ-ONLY-FOO))
=> 2
;; #2: This constructs a form and then uses it in two places in another
;; constructed form. Each of the uses is in a different lexical
;; contour, so must be expanded differently.
(LET ((FOO (LIST 'FOO)))
(EVAL `(LIST (MACROLET ((FOO (&WHOLE FORM) '(+ 1 1))) ,FOO)
(MACROLET ((FOO (&WHOLE FORM) '(+ 1 2))) ,FOO))))
=> (2 3)
;; #3: This is effectively the same thing but involves a MACROLET
;; shadowing a DEFMACRO rather than two MACROLETs, since some
;; implementations might only be caching expansions that come
;; from DEFMACRO.
(DEFMACRO FOO (&WHOLE FORM) '(+ 1 1))
(LET ((FOO (LIST 'FOO)))
(EVAL `(LIST ,FOO (MACROLET ((FOO (&WHOLE FORM) '(+ 1 2))) ,FOO))))
=> (2 3)
Current Practice:
Symbolics Genera does not use displacing or table caching in either
the interpreter or compiler.
Symbolics Cloe, a compiled only implementation, uses table caching
to boost compilation by a little. Running the test cases above turned
up a bug (in test case #3), which is now in the process of being fixed.
[The fact that a bug was turned up in code written by a CL implementor
is an existence proof that the potential for trouble was not imagined.]
Both Symbolics Cloe and Symbolics Genera support *MACROEXPANSION-HOOK*,
leaving open the possibility of users bringing disasters upon themselves.
Macro environment objects in Symbolics Genera are stack-allocated, so
have only dynamic extent.
Cost to Implementors:
This proposal is upward compatible with correct implementations.
Cost to Users:
There is no cost to users of the RESTRICT proposal, unless they were doing
semantically invalid caching.
The cost to users of the DISALLOW proposal is a loss of speed in some cases
which are semantically valid. In general, however, the efficiency and
usefulness of such caching is subject to question in code intended to be
ported. Given that implementations are not required to ever give the same
environment object twice, the caching may be all for naught in some
implementations.
Cost of Non-Adoption:
Continued widespread confusion about whether displacement is a legitimate
implementation technique for user code.
Benefits:
Since *MACROEXPANSION-HOOK* is in the Lisp package, multiple applications
in the same environment share its effects. Often one application will
clobber another's hook, or introduce a hook that is not desirable to other
applications when none previously existed. Since a common use of
*MACROEXPANSION-HOOK* is to install a macro caching mechanism, clarifying
the situations in which *MACROEXPANSION-HOOK* should not be used will
decrease the likelihood of one program breaking, slowing down, or otherwise
adversely affecting another.
Aesthetics:
Most people agree that macro caching techniques are only supposed to improve
speed without affecting semantics. This proposal is only intended to
underscore that necessary truth. Insofar as this is only a clarification,
it presumably has no significant aesthetic impact.
Discussion:
Pitman thinks it's a good idea to clarify this issue because it's not really
spelled out now and it's the sort of thing programmers can waste a lot of
time bickering about to no good end. Either the functionality is reliable
and should be encouraged, or it is not reliable and should be discouraged
or forbidden. Pitman supports the DISALLOW proposal because it leaves open
the possibility of making macro environments have dynamic extent, but he
can live with the RESTRICT position, which he believes represents the
status quo.
Bob Laddaga (a Cloe maintainer who reviewed a draft of this proposal)
supports the DISALLOW option as well.
∂01-Feb-89 0550 CL-Compiler-mailer Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 1 Feb 89 05:49:03 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04912; 1 Feb 89 13:19 GMT
Date: Wed, 1 Feb 89 13:32:41 GMT
Message-Id: <5636.8902011332@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue CONSTANT-CIRCULAR-COMPILATION, version 4
To: Jon L White <@sail.stanford.edu:jonl@lucid.com>
In-Reply-To: Jon L White's message of Tue, 31 Jan 89 01:51:53 PST
Cc: cl-compiler@sail.stanford.edu
> unless more than one weirded-out user falls upon it as follows:
> (1) It is a natural case of some money-earning software product, and
> not just another exercise to show how bad someone's compiler is;
> (2) The time saved by a special-case switch to turn off the tabling
> algorithms can be translated into a real dollars-and-cents profit
One of the pragmatist philosophers (James? Dewey?) used to talk about
the "cash value" of things -- i.e., what difference did it make. It's
reasonable to think that way. But it's not so reasonable to insist that
the only thing that matters is "money-earning software". I do not think
that commercial considerations full stop should decide any issue.
That said, however:
> re: I think any serious implementation of COMPILE-FILE will quietly handle
> circular data, just as any serious garbage collector is expected to.
>
> Well-said, Jim!
Exactly.
But for me the deciding factor is that I can write circular constants
in source code. I don't like the idea of a language that can't compile
its own source notation. (#. is a pain, but I'm willing to keep it).
∂01-Feb-89 1415 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 1 Feb 89 14:15:46 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA06474; Wed, 1 Feb 89 15:13:07 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA27088; Wed, 1 Feb 89 15:12:46 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902012212.AA27088@defun.utah.edu>
Date: Wed, 1 Feb 89 15:12:44 MST
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: David N Gray <Gray@DSG.csc.ti.com>,
Sandra J Loosemore <sandra%defun@cs.utah.edu>,
KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 27 Jan 89 22:03 EST
I'd like to get this issue out of the way. To me it appears that we
have pretty much reached a consensus, and the remaining obstacle is
deciding upon some exact wording. Here is my suggestion for an
amendment.
Remove the paragraph from proposal LOAD-TIME-EVAL:R**2-NEW-SPECIAL-FORM
that begins "Implementations must guarantee that each reference....".
Replace it with:
Within a single call to EVAL, COMPILE, or COMPILE-FILE,
implementations are permitted to coalesce EQ LOAD-TIME-VALUE
expressions (that is, lists of the form (LOAD-TIME-VALUE ...) that are
EQ) appearing textually within the code being processed. Since a
LOAD-TIME-VALUE expression may be referenced in more than one place,
users must use caution when destructively modifying the resulting
object, as there may be other references to the object.
If any of you have some alternate wording you'd prefer to see, or or
some additional changes to include in the amendment, I'll be happy to
entertain further suggestions (but please try to be specific).
-Sandra
-------
∂01-Feb-89 1510 CL-Compiler-mailer issue COMPILE-FILE-SYMBOL-HANDLING, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 1 Feb 89 15:10:25 PST
Received: from defun.utah.edu by cs.utah.edu (5.59/utah-2.1-cs)
id AA08200; Wed, 1 Feb 89 16:07:53 MST
Received: by defun.utah.edu (5.59/utah-2.0-leaf)
id AA27150; Wed, 1 Feb 89 16:07:36 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902012307.AA27150@defun.utah.edu>
Date: Wed, 1 Feb 89 16:07:34 MST
Subject: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
To: cl-compiler@sail.stanford.edu
Cc: moon@stony-brook.scrc.symbolics.com
This is a new issue, split off from CONSTANT-COMPILABLE-TYPES and the
cl-cleanup issue IN-PACKAGE-FUNCTIONALITY. The writeup is rather
long, with three proposals and an analysis section at the end that
compares them.
Forum: Compiler
Issue: COMPILE-FILE-SYMBOL-HANDLING
References: CLtL p. 182
Issue IN-PACKAGE-FUNCTIONALITY
Issue CONSTANT-COMPILABLE-TYPES
Issue DEFPACKAGE (passed)
Category: CHANGE/CLARIFICATION
Edit History: V1, 01 Feb 1989, Sandra Loosemore
Status: **DRAFT**
Problem Description:
It is not clear how COMPILE-FILE is supposed to specify to LOAD how
symbols in the compiled file should be interned. In particular, what
happens if the value of *PACKAGE* is different at load-time than it
was at compile-time, or if any of the packages referenced in the file
are defined differently?
There are three proposals: CURRENT-PACKAGE, HOME-PACKAGE, and
REQUIRE-CONSISTENCY.
Proposal COMPILE-FILE-SYMBOL-HANDLING:CURRENT-PACKAGE:
When a compiled file is loaded, the interned symbols it references
are found by the following procedure. The rules are applied in the
order listed and only the first applicable rule has any effect.
(1) Any symbol accessible at compile time in the package that is the
value of *PACKAGE* is found by calling INTERN at load time with one
argument, the name of the symbol.
(2) A keyword symbol is found by finding or creating a keyword symbol
with the same name.
(3) A symbol that at compile time is an external symbol of its home
package is found at load time by finding the package with the same
name as the compile-time home package, and then finding an exported
symbol of that package with the same name as the compile-time symbol.
If no such package exists, no such symbol exists, or the symbol is not
exported, an error is signalled.
(4) Any other symbol is found by calling INTERN at load time with two
arguments, the name of the symbol and the package with the same name
as the compile-time symbol's home package. If no such package exists,
an error is signalled.
The goal of this procedure is for each symbol reference to be
resolved to the same symbol when a compiled file is loaded as when
the source file is loaded directly with LOAD. It is possible to
create package structures that make that impossible; for example, it
is possible for a symbol to be inaccessible from its own home
package. A conforming program cannot depend on any symbol
resolution behavior that is not provided by the above four rules.
If any top level form in a compiled file changes the value of
*PACKAGE*, other than a SELECT-PACKAGE appearing as the first
top level form in the file, the results are unspecified.
Rationale:
Proposal CURRENT-PACKAGE makes COMPILE-FILE/LOAD follow the same
rules as PRINT/READ. For any symbol not written with a package
prefix in the source file (which should be the great majority of
them), CURRENT-PACKAGE will make loading the compiled file get the
same symbols as loading the source file.
The reason for the rule about changing the value of *PACKAGE* is that
many loaders cache the interning of symbols; if the same symbol
appears multiple times in the source file, its name may only be
looked up once at load time. Since not all loaders are required to
work this way, changing *PAKCAGE* in mid-file is not allowed,
because the effect on later occurrrences of a symbol would be
implementation-dependent.
Proposal COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE:
When a compiled file is loaded, the interned symbols it references are
found by calling INTERN at load time with two arguments, the name of
the symbol and the package with the same name as the compile-time
symbol's home package. If no such package exists, an error is
signalled.
The goal of this procedure is for each symbol reference to be resolved
to the same symbol when a compiled file is loaded as when the source
file was processed by COMPILE-FILE. A conforming program cannot
depend on any symbol resolution behavior that is not provided by the
above rule.
If any top level form in a compiled file changes the value of
*PACKAGE* when the file is loaded interpretively but not during
compile-time processing by COMPILE-FILE, the results are unspecified.
Rationale:
The behavior specified in this proposal is simple and easy to
understand (there is only one rule to remember instead of four).
It does not require any restrictions on where top-level
SELECT-PACKAGE forms may appear in the file. It allows a compiled
file that does not include an explicit SELECT-PACKAGE to be loaded
successfully no matter what the load-time value of *PACKAGE* is,
as long as the compile-time value of *PACKAGE* was the "right"
package.
Proposal COMPILE-FILE-SYMBOL-HANDLING:REQUIRE-CONSISTENCY:
In order to guarantee that compiled files can be loaded correctly,
users must ensure that the packages referenced in the file are defined
consistently at compile and load time. Conforming Common Lisp programs
must satisfy the following requirements:
(1) The value of *PACKAGE* when the contents of the file are compiled
by COMPILE-FILE must be the same as the value of *PACKAGE* when
the file is loaded. In particular:
(a) If any top level form in a compiled file changes the value
of *PACKAGE*, other than a SELECT-PACKAGE appearing as the first
top-level form in the file, the results are unspecified.
(b) If the first top-level form in the file is not a call to
SELECT-PACKAGE, then the value of *PACKAGE* at the time LOAD is
called must be a package with the same name as the package that
was the value of *PACKAGE* at the time COMPILE-FILE was called.
(2) For all symbols that were accessible in *PACKAGE* at compile
time but whose home package was another package, at load time there
must be a symbol with the same name that is accessible in both the
load-time *PACKAGE* and in the package with the same name as the
compile-time home package.
(3) For all symbols in the compiled file that were external symbols in
their home package at compile time, there must be a symbol with the
same name that is an external symbol in the package with the same name
at load time.
If any of these conditions do not hold, the package in which the
affected symbols are interned by LOAD is unspecified. Implementations
are permitted to signal an error or otherwise define this behavior.
Otherwise, when a compiled file is loaded, the interned symbols it
references are found by calling INTERN at load time with two
arguments, the name of the symbol and the package with the same name
as the compile-time symbol's home package. If no such package exists,
an error is signalled.
Rationale:
Any program that behaves differently under the other two proposals
is already nonportable. This proposal is merely an explicit
statement of the status quo, namely that users cannot depend on
any particular behavior if the package environment at load time is
inconsistent with what existed at compile time.
Current Practice:
PSL/PCLS implements something very similar to proposal HOME-PACKAGE,
as does A-Lisp. Utah Common Lisp implements something like proposal
CURRENT-PACKAGE, but the chief compiler hacker says he thinks that
proposal HOME-PACKAGE actually makes more sense, and agrees that any
program that behaves differently under the two proposals is broken.
KCL implements something like HOME-PACKAGE (symbols in the compiled
file are explicitly qualified with the name of their home package),
except that it differentiates between internal and external symbols.
Lucid Lisp appears to implement something like proposal CURRENT-PACKAGE.
Symbolics Genera implements CURRENT-PACKAGE. Symbolics Cloe probably
does also.
Cost to implementors:
Proposals HOME-PACKAGE and CURRENT-PACKAGE would be incompatible
changes for implementations that currently do things the other way.
It would probably be easier to convert to HOME-PACKAGE than
CURRENT-PACKAGE, since it is less complicated.
Proposal REQUIRE-CONSISTENCY is intended to be compatible with either
of the other two proposals, but it may not be entirely compatible with
the details of current implementations.
Cost to users:
Proposal HOME-PACKAGE places the fewest restrictions on user programs.
Proposal CURRENT-PACKAGE places a restriction on where and how the value
of *PACKAGE* may be changed within the file.
Proposal REQUIRE-CONSISTENCY places even more restrictions on user
programs.
Most of these restrictions are probably already necessary in portable
programs. However, some nonportable programs that depend on the "other"
model may be broken by proposals HOME-PACKAGE or CURRENT-PACKAGE.
For a discussion of how these proposals treat nonportable or erroneous
programs, see the "Analysis" section below.
Benefits:
COMPILE-FILE's treatment of symbols is made explicit in the standard.
Analysis:
Proposals CURRENT-PACKAGE and HOME-PACKAGE present two different
models of how this problem might be solved. Essentially, proposal
CURRENT-PACKAGE uses the same rules as PRINT/READ in deciding when to
qualify symbols with a package name and where to find unqualified
symbols. Proposal HOME-PACKAGE requires -all- symbols written to the
compiled file to be qualified with an explicit package, and the loader
simply interns the symbols in that package.
These two proposals differ in the following situations. Proposal
REQUIRE-CONSISTENCY, in effect, says that valid programs do not cause
any of these situations to occur, and the behavior in such cases is
unspecified (allowing both models to be used as valid implementation
techniques).
(1) The situation where the file does not contain a SELECT-PACKAGE
and where the compile-time value of *PACKAGE* is a package with a
different name than the load-time value of *PACKAGE*.
Proposal CURRENT-PACKAGE would intern symbols that were accessible
in *PACKAGE* at compile time in *PACKAGE* at load time.
Proposal HOME-PACKAGE would intern symbols that were accessible in
*PACKAGE* at compile time in the package with the same name as
their compile-time home package.
In general, programs must be compiled in the "right" package, so
that the compiler can find and apply the correct macro expansions,
type definitions, and so on; see issue COMPILE-ENVIRONMENT-CONSISTENCY.
As a result of macroexpansion or other transformations applied by
the compiler, the compiled file may contain symbol references that
were not present in the source file. Proposal CURRENT-PACKAGE may
cause problems because these references may be resolved to be
symbols other than the ones that were intended. Since proposal
HOME-PACKAGE remembers the home package of all symbols, it is much
more likely to find the correct symbols at load time.
(2) The situation where *PACKAGE* is altered by a top-level form
that is not a SELECT-PACKAGE which is the first top-level form in
the file.
Proposal CURRENT-PACKAGE says this is illegal.
Proposal HOME-PACKAGE says this is OK, as long as *PACKAGE* is
altered in the same way at compile time as when the file is loaded
interpretively. This is possible because the behavior this
proposal specifies does not depend on what the value of *PACKAGE*
is once symbols in the source file have been read by COMPILE-FILE.
Some people argue that allowing *PACKAGE* to be switched in
mid-file is a bad idea anyway; it is not really necessary and it
implies a restriction on COMPILE-FILE to read forms from the file
one at a time, processing each form before the next call to READ.
Others argue that restricting SELECT-PACKAGE to be the first
top-level form is an artificial contrivance. The compile-time
behavior of SELECT-PACKAGE is well-defined no matter where it
appears in the file. There is also a problem defining what "the
first top-level form" really means. Finally, this model requires
all package definitions to be made externally to the file, which
may be inconvenient for smaller programs that now contain the
package definition and package contents all in one file.
(3) The situation where there is a symbol accessible in the
compile-time value of *PACKAGE* but with another home package, and
where at load time there is not a symbol with the same name that
is accessible in both packages. This situation might occur, for
example, if at compile time there is a symbol that is external in
its home package and that package is used by *PACKAGE*, but where
there is no such external symbol in that package at load time, or
the load-time *PACKAGE* does not use the other package.
Proposal CURRENT-PACKAGE would find or create a symbol accessible
in *PACKAGE*.
Proposal HOME-PACKAGE would find or create a symbol accessible in
a package with the same name as the symbol's compile-time home
package.
Some people feel that the behavior of proposal CURRENT-PACKAGE is
more intuitive in this situation, and that it is more forgiving of
differences between the compile-time and load-time package
structures. Others feel that the behavior of HOME-PACKAGE is more
intuitive, and that if there have been significant changes to the
package structures, it is probably an indication that the file
needs to be recompiled anyway, since the compiler might have
picked up macro definitions and the like from the wrong package.
(4) The situation where a symbol is external in its home package
and where there is no such external symbol in that package at load
time.
Proposal CURRENT-PACKAGE would quietly intern the symbol in
*PACKAGE* if the symbol were accessible in *PACKAGE* at compile
time. Otherwise, it will signal an error.
Proposal HOME-PACKAGE would always just quietly intern the symbol
as internal in its home package.
Not complaining when a symbol that is supposed to be external
isn't can be seen as a violation of modularity. However, it seems
like this argument should apply equally to symbols whose home
package is *PACKAGE* as symbols whose home package is somewhere
else.
Discussion:
Loosemore is opposed to proposal CURRENT-PACKAGE, but would be
less opposed to it if it contained an explicit statement that
*PACKAGE* must be a package with the same name at load time as at
compile time.
Moon is opposed to proposal HOME-PACKAGE, but would be less
opposed to it if it required an error to be signalled when a
symbol that was external at compile time is not external at load
time.
-------
∂01-Feb-89 1554 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 1 Feb 89 15:54:26 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 532068; Wed 1-Feb-89 18:50:50 EST
Date: Wed, 1 Feb 89 18:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: David N Gray <Gray@DSG.csc.ti.com>, KMP@STONY-BROOK.SCRC.Symbolics.COM,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <8902012212.AA27088@defun.utah.edu>
Message-ID: <19890201235118.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 1 Feb 89 15:12:44 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
I'd like to get this issue out of the way. To me it appears that we
have pretty much reached a consensus, and the remaining obstacle is
deciding upon some exact wording. Here is my suggestion for an
amendment.
Remove the paragraph from proposal LOAD-TIME-EVAL:R**2-NEW-SPECIAL-FORM
that begins "Implementations must guarantee that each reference....".
Replace it with:
Within a single call to EVAL, COMPILE, or COMPILE-FILE,
implementations are permitted to coalesce EQ LOAD-TIME-VALUE
expressions (that is, lists of the form (LOAD-TIME-VALUE ...) that are
EQ) appearing textually within the code being processed. Since a
LOAD-TIME-VALUE expression may be referenced in more than one place,
users must use caution when destructively modifying the resulting
object, as there may be other references to the object.
If any of you have some alternate wording you'd prefer to see, or or
some additional changes to include in the amendment, I'll be happy to
entertain further suggestions (but please try to be specific).
Well, I agree with the idea that when a form (LOAD-TIME-VALUE <form>)
is referenced from more than one place (compare be EQ), the system
is not required to evaluate the inner <form> more than once. The attempts
to define it otherwise just weren't working.
However, you've put in the phrase "Within a single call to EVAL" and I
cannot imagine what that actually means (because EVAL is recursive). I
don't think you responded to David Gray's objections to that phrase. Is
there any reason for it? How about the following wording instead?
Remove the three paragraphs from proposal
LOAD-TIME-EVAL:R**2-NEW-SPECIAL-FORM that begin "Note that, in
interpreted code, ...", "Implementations must guarantee that each
reference....", and "In the case of a LOAD-TIME-VALUE form appearing
in a quoted expression passed to EVAL...". Replace those three
paragraphs with:
If the same (compared with EQ) list (LOAD-TIME-VALUE <form>) is
evaluated or compiled more than once, it is unspecified whether <form>
is evaluated only once or is evaluated more than once. This can
happen both when an expression being evaluated or compiled shares
substructure, and when the same expression is passed to EVAL or to
COMPILE multiple times. Since a LOAD-TIME-VALUE expression may be
referenced in more than one place and may be evaluated multiple times
by the interpreter, it is unspecified whether each execution returns
a "fresh" object or returns the same object as some other execution.
Users must use caution when destructively modifying the resulting
object.
If two lists (LOAD-TIME-VALUE <form>) are EQUAL but not EQ, their
values always come from distinct evaluations of <form>. Coalescing
of these forms is not permitted.
Note that I have removed all the vague wording that I objected to and
have removed the inconsistencies between the interpreter and the
compiler, except for the requirement that (similar to macros) after
COMPILE or COMPILE-FILE all the load time values are guaranteed to be
resolved, whereas the interpreter remains free not to cache. I'm
much happier with this wording than with what you proposed.
∂01-Feb-89 1609 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 1 Feb 89 16:09:20 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 532087; Wed 1-Feb-89 19:06:24 EST
Date: Wed, 1 Feb 89 19:06 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: sandra%defun@cs.utah.edu, Gray@DSG.csc.ti.com,
KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <19890201235118.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <890201190608.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
I may have more to say on this later, but for now...
Date: Wed, 1 Feb 89 18:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
...
If two lists (LOAD-TIME-VALUE <form>) are EQUAL but not EQ, their
values always come from distinct evaluations of <form>. Coalescing
of these forms is not permitted.
But since compilers can coalesce the constant structure in forms like
(DEFUN FOO ()
(LIST (EVAL '(LOAD-TIME-VALUE (BAR)))
(EVAL '(LOAD-TIME-VALUE (BAR)))))
then distinct forms may sometimes ultimatley get coalesced anyway, so
this may look more re-assuring than it really is.
Btw, Sandra's references to "calls to EVAL" meant toplevel calls. After
all, users can't tell if EVAL is implemented recursively, or if some
internal function is used to do the recursion. The only time they ever
come in contact with the recursive nature is when they use EVALHOOK, and
there it is not EVAL, but EVALHOOK which accomplishes the recursion.
∂02-Feb-89 0848 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Feb 89 08:47:39 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 532381; Thu 2-Feb-89 11:44:21 EST
Date: Thu, 2 Feb 89 11:44 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
cc: sandra%defun@cs.utah.edu, Gray@DSG.csc.ti.com, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <890201190608.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-ID: <19890202164457.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 1 Feb 89 19:06 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
I may have more to say on this later, but for now...
Date: Wed, 1 Feb 89 18:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
...
If two lists (LOAD-TIME-VALUE <form>) are EQUAL but not EQ, their
values always come from distinct evaluations of <form>. Coalescing
of these forms is not permitted.
But since compilers can coalesce the constant structure in forms like
(DEFUN FOO ()
(LIST (EVAL '(LOAD-TIME-VALUE (BAR)))
(EVAL '(LOAD-TIME-VALUE (BAR)))))
then distinct forms may sometimes ultimatley get coalesced anyway, so
this may look more re-assuring than it really is.
Agreed.
Btw, Sandra's references to "calls to EVAL" meant toplevel calls. After
all, users can't tell if EVAL is implemented recursively, or if some
internal function is used to do the recursion. The only time they ever
come in contact with the recursive nature is when they use EVALHOOK, and
there it is not EVAL, but EVALHOOK which accomplishes the recursion.
I still don't think it means anything. For example, in your FOO example
the two calls to EVAL inside the list are top-level calls if FOO was called
from something compiled, or non-top-level calls if FOO was called from
something interpreted. Does the Lisp's interactive loop count as EVAL?
What if it's executing a LOAD command, or loading a user's lisp init file,
rather than evaluating a typed-in form? I still don't think it means anything.
∂02-Feb-89 0908 CL-Compiler-mailer Re: Issue: LOAD-TIME-EVAL (Version 8)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Feb 89 09:08:36 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 532416; Thu 2-Feb-89 12:04:52 EST
Date: Thu, 2 Feb 89 12:04 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: LOAD-TIME-EVAL (Version 8)
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, sandra%defun@cs.utah.edu,
Gray@DSG.csc.ti.com, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <19890202164457.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <890202120434.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Thu, 2 Feb 89 11:44 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
...
Btw, Sandra's references to "calls to EVAL" meant toplevel calls. After
all, users can't tell if EVAL is implemented recursively, or if some
internal function is used to do the recursion. The only time they ever
come in contact with the recursive nature is when they use EVALHOOK, and
there it is not EVAL, but EVALHOOK which accomplishes the recursion.
I still don't think it means anything. For example, in your FOO example
the two calls to EVAL inside the list are top-level calls if FOO was called
from something compiled, or non-top-level calls if FOO was called from
something interpreted. Does the Lisp's interactive loop count as EVAL?
What if it's executing a LOAD command, or loading a user's lisp init file,
rather than evaluating a typed-in form? I still don't think it means anything.
Sigh... The particular feature I'm worried about is not something I have
have a clear example of, nor is it something any code I have depends on
now. I suspect that if I had an actual case it would be easier to say
what the right thing was (including the possibility of realizing that
the example was bogus).
I guess I think the right thing to avoid deadlock here is just to carve out
a paragraph in the discussion that says something like:
Pitman was somewhat concerned that coalescing LOAD-TIME-VALUE results
based on EQ-ness of the LOAD-TIME-VALUE form could conceivably lead to
trouble down the line. However, since he could provide no actual examples
to back up that worry, and since the majority opinion was that some
implementations would find a restriction against such coalescing an
undue burden, the decision was made to just `note the concern' and
proceed on.
∂02-Feb-89 1239 CL-Cleanup-mailer Issue: FUNCTION-NAME (Version 1)
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 2 Feb 89 12:39:51 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA12354; Thu, 2 Feb 89 12:39:31 PST
Received: from lukasiewicz.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA28202; Thu, 2 Feb 89 12:36:18 PST
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA00560; Thu, 2 Feb 89 12:39:12 PST
Date: Thu, 2 Feb 89 12:39:12 PST
From: jrose@Sun.COM (John Rose)
Message-Id: <8902022039.AA00560@lukasiewicz.sun.com>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: CL-Cleanup@SAIL.STANFORD.EDU, CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Fri, 27 Jan 89 22:48 EST <19890128034814.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue: FUNCTION-NAME (Version 1)
I favor the FUNCTION-NAME:LARGE proposal, because it defines a single,
useful notion of what a function name is. The other proposals have
the flaw that there are two kinds of function names: symbols, and
extended names, with only some of the Lisp primitives accepting the
latter. This may be convenient for some implementations, for the
short term, but it fragments the language.
I have two other comments on the proposal.
A. Reducing the Cost to Implementors
One observation you could put in the Cost To Implementors section is
that none of the SMALL, MEDIUM, or LARGE proposals require changes to
the "guts" of the interpreter and compiler. This is because an
implementation is free to use plain symbols internally to name
functions, and use a hack like JonL's SETF:|3.FOO.BAR| mapping to
convert non-symbol names to symbols. This conversion would be done as a
part of parsing the handful of forms which accept function names, and
then all other passes of the interpreter and compiler (the "guts") would
just see symbols. (By "parsing" I mean ensuring the right number and
type of syntactic subforms. You can see that this is a very early and
simple stage of processing.) Or, Lisp compilers with an "alphatization"
phase could perform function name symbolization at that phase.
B. Finishing the Job of Regularization
I'd like to suggest two additions to your smorgasbord of options in the
FUNCTION-NAME:LARGE section of the proposal. One addition would
regularize a major special case of functions--lambda expressions. The
other addition would reaffirm an unstated regularity in the language,
that function names can stand in for functions under FUNCALL and APPLY.
Not only can the treatment of symbolic and setf-list function names be
regularized, but lambda too can be treated in a consistent manner.
If these two points are added to your proposal, the language as a whole
would have a completely uniform treatment of functions and function
names. Here they are:
13. Declare that any function name is a suitable argument to FUNCALL and
APPLY. In such a case, the function name is passed to FDEFINITION,
and the result (which may in turn be a function name) is called.
That is, the following two expressions are equivalent, when fname
is a function name:
(FUNCALL fname x y)
<==>
(FUNCALL (FDEFINITION fname) x y)
Note that the definition is sought in the global environment.
Compare with the rule which applies to a function name occurs,
syntactically, as the car of a list in code:
(fname x y)
<==>
(FUNCALL (FUNCTION fname) x y)
<==> (under proposal item 9)
(FUNCALL (FDEFINITION fname <local-environment>) x y)
12. Declare that any lamba expression (i.e., a list whose car is LAMBDA and
whose cdr is a well-formed lambda argument list and body) is a function
name. The effects of the function name accessors on lambda expressions
are as follows. FDEFINITION returns an implementation-defined value which
is the function specified the lambda expression, closed in the global
environment. This FDEFINITION value cannot be changed by SETF.
FBOUNDP always returns T, and MAKUNBOUND is an error.
Esthetics:
The effect of items 11 and 12 is to complete the regularization of
Common Lisp's treatment of functions and function names. The total
effect of proposal items 1 through 12 is that Lisp has just two notions
for referencing function objects: FUNCTIONS, which are Lisp objects that
directly represent executable code, and FUNCTION NAMES, which can denote
functions. Symbols, SETF function names, and lambda expressions are all
examples of the latter notion. The former notion is highly
implementation dependent. Function names can occur as syntactic
entities in code. FUNCALL and APPLY work uniformly on both functions
and function names, with a consistent semantics.
Lambda expressions are often thought to denote "anonymous" functions, so
it may seem paradoxical to treat them as names. The paradox is only
apparent, since the expression itself has the properties of a Lisp
function name: It is (typically) a cons tree which can be read, printed,
and stored in source files, and it denotes a well-defined Lisp function.
Benefit to Users:
Function names are useful for representing objects in remote
environments, because they need not be bound at all times to the same
function, or to any function, and because they are typically stable in
meaning across reads and prints, where plain functions are not.
Programs which deal simultaneously with remote and local environments,
such as CLOS, can probably be simplified, since function names
can be used uniformly, rather than an ad-hoc mixture of functions
and function names.
The language as a whole become more uniform from these additions and
clarifications, making it easier to learn and use. (See Esthetics.)
Cost to Implementors:
Interpreters which currently have a special case check for application
of lambda expressions would need to modify this check to call
FDEFINITION when a list of any sort is encountered. Note that all
Common Lisps already must perform some such check, since lambda
expressions can be funcalled (and this is currently a very special case,
the only standard case of a list being funcalled). This means that
every Lisp already has a place to insert the required call to
FDEFINITION.
In some implementations, FDEFINITION of a lambda expression could be that
lambda-expression itself. In others featuring a pre-eval codewalk, the
walk would be done by FDEFINITION, which would return an appropriate
closure.
Cost of Non-adoption:
Rather than two notions for function references (functions and function
names), there would be several notions, each corresponding to the valid
inputs for particular group of primitives. APPLY and FUNCALL would
accept functions, symbolic names, and lambda expressions, but not setf
function names. FDEFINITION and its kind would accept symbols and setf
function names but not lambda expressions. If the :LARGE proposal is
not adopted, this fragmentation would also apply to the various syntaxes
involving function names; some names would be acceptable to DEFUN
but not to FLET, etc.
-- John
∂03-Feb-89 0820 CL-Compiler-mailer Re: Issue: FUNCTION-NAME (Version 1)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 3 Feb 89 08:19:54 PST
Received: by ti.com id AA13550; Fri, 3 Feb 89 10:17:57 CST
Received: from Kelvin by tilde id AA18146; Fri, 3 Feb 89 10:06:53 CST
Message-Id: <2811514004-8355350@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 3 Feb 89 10:06:44 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: jrose@Sun.COM (John Rose)
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Cleanup@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
Subject: Re: Issue: FUNCTION-NAME (Version 1)
In-Reply-To: Msg of Thu, 2 Feb 89 12:39:12 PST from jrose@Sun.COM (John Rose)
> 13. Declare that any function name is a suitable argument to FUNCALL and
> APPLY. In such a case, the function name is passed to FDEFINITION,
> and the result (which may in turn be a function name) is called.
I don't think this is such a good idea. The case of automatically coercing
a symbol to a function is needed because it provides a portable mechanism
for indirect addressing of a function; I haven't seen a reason to need this
for non-symbol function specs. But more important is that coercing a
symbol to a function is a trivial operation that is reasonable to do at
run time on each call without adding a significant amount of overhead.
FDEFINITION, on the other hand, is a much more expensive operation -- at
best it might use GET to do a property list lookup, or it could be using
string-append and INTERN to convert the name to a symbol. In either case,
I think this is more work than you want to do on each call.
> 12. Declare that any lamba expression (i.e., a list whose car is LAMBDA and
> whose cdr is a well-formed lambda argument list and body) is a function
> name. The effects of the function name accessors on lambda expressions
> are as follows. FDEFINITION returns an implementation-defined value which
> is the function specified the lambda expression, closed in the global
> environment. This FDEFINITION value cannot be changed by SETF.
> FBOUNDP always returns T, and MAKUNBOUND is an error.
The exceptions for SETF and MAKUNBOUND show that this is not really as
consistent as you might like. Furthermore, the FUNCTION special form would
have to treat a LAMBDA expression as a function, not a function name, in
order for it to be lexically scoped. It seems like this might just cause
confusion rather than consistency.
∂03-Feb-89 0821 CL-Compiler-mailer Issue: LOAD-TIME-EVAL (Version 8)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 3 Feb 89 08:21:25 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04241g; Fri, 3 Feb 89 08:13:13 PST
Received: by bhopal id AA04587g; Fri, 3 Feb 89 08:15:34 PST
Date: Fri, 3 Feb 89 08:15:34 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8902031615.AA04587@bhopal>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, sandra%defun@cs.utah.edu,
Gray@DSG.csc.ti.com, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: Kent M Pitman's message of Thu, 2 Feb 89 12:04 EST <890202120434.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-TIME-EVAL (Version 8)
re: I guess I think the right thing to avoid deadlock here is just to carve out
a paragraph in the discussion that says something like:
Pitman was somewhat concerned that coalescing LOAD-TIME-VALUE results
based on EQ-ness of the LOAD-TIME-VALUE form could conceivably lead to
trouble down the line. However, since he could provide no actual examples
to back up that worry, and since the majority opinion was that some
implementations would find a restriction against such coalescing an
undue burden, the decision was made to just `note the concern' and
proceed on.
Count me in too on exactly the same feelings. I think the "correct"
behaviour for EQ instances in differing functions could be well
specified if we required a "pre-pass" interpreter. However, since
I'm against that requirement and don't see any other reasonable way
to specify the "correct" behaviour, then I would concur with your
opinion expressed above.
-- JonL --
∂03-Feb-89 0949 CL-Compiler-mailer Re: Issue: MACRO-CACHING (Version 1)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 3 Feb 89 09:49:12 PST
Received: by ti.com id AA13923; Fri, 3 Feb 89 11:48:02 CST
Received: from Kelvin by tilde id AA20474; Fri, 3 Feb 89 11:38:57 CST
Message-Id: <2811519532-8687489@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 3 Feb 89 11:38:52 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU
Subject: Re: Issue: MACRO-CACHING (Version 1)
In-Reply-To: Msg of Tue, 31 Jan 89 19:35 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
I can accept MACRO-CACHING:DISALLOW.
The Explorer evaluator does displacement of macros, but is careful to
correctly handle the cases exemplified in your test cases #1 and #2.
It does not do the right thing for #3, but that is a bug that can fairly
easily be fixed.
∂05-Feb-89 2333 CL-Compiler-mailer Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
Received: from EDDIE.MIT.EDU by SAIL.Stanford.EDU with TCP; 5 Feb 89 23:33:21 PST
Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id <AA24411@EDDIE.MIT.EDU>; Mon, 6 Feb 89 02:31:18 EST
Received: by spt.entity.com (smail2.5); 6 Feb 89 01:54:53 EST (Mon)
To: sandra%defun@cs.utah.edu
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Sandra J Loosemore's message of Wed, 25 Jan 89 09:16:50 MST <8901251616.AA20436@defun.utah.edu>
Subject: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
Message-Id: <8902060154.AA17328@spt.entity.com>
Date: 6 Feb 89 01:54:53 EST (Mon)
From: gz@spt.entity.com (Gail Zacharias)
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Date: Wed, 25 Jan 89 09:16:50 MST
Item 2c (block compilation) has been more controversial -- KCL does
this, but many people seem to think that this should not be the
default behavior of the compiler. My plan for voting on this issue at
the last meeting was to first ask for a vote on an amendment to remove
this particular item, but it never got that far. I suppose that if
nobody speaks up for it in the meantime, we could just go ahead and
remove it from the next version.
Well, I'm speaking up for it. This item has nothing to do with whether
anybody does it by default, and a lot to do with whether a block-compilation
option can be made available to *users* of Common Lisp programs (you know,
those people twice removed from implementors that we're doing all this for).
The question is whether an end user can take a Common Lisp program whose
internals he's not familiar with, block-compile it, and be guaranteed that it
will continue to function correctly. This item says that yes, a correct CL
program must explicitly indicate what functions in the source it will redefine
at runtime. I don't think this places such a great burden on the programmer.
Without this provision, only somebody intimately familiar with a program could
know whether it can be safely block-compiled, making block-compilation useless
in the context of portable CL programs.
This thing about "block compilation shouldn't be the default" seems to come up
every time this item is discussed. That's an environment question and is not
addressed by the proposal. The proposal simply says that block compilation
should be legal. Maybe some explanation of this can be placed in somewhere in
the proposal to avoid repeating this discussion at the next meeting...
∂06-Feb-89 0836 CL-Compiler-mailer Re: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 6 Feb 89 08:35:41 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa05650; 6 Feb 89 15:57 GMT
Date: Mon, 6 Feb 89 16:14:34 GMT
Message-Id: <16209.8902061614@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue: COMPILE-ENVIRONMENT-CONSISTENCY (Version 3)
To: Gail Zacharias <gz%spt.entity.com@NSS.Cs.Ucl.AC.UK>,
sandra <@cs.utah.edu:sandra@defun>
Cc: Moon@scrc-stony-brook.arpa, CL-Compiler@sail.stanford.edu
> From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Wed, 25 Jan 89 09:16:50 MST
> Item 2c (block compilation) has been more controversial -- KCL does
> this, but many people seem to think that this should not be the
> default behavior of the compiler.
Some Common Lisps do self-tail calls without going through the
SYMBOL-FUNCTION.
What KCL does is this. A Lisp rpocedure is compiled as a C procedure.
For calls across files, KCL compiles compiles code that gets the
function definition from that symbol that is its name. For calls
within the same file, KCL just emits a call to the C procedure
directly. So, redefinitions at the Lisp level have no effect on such
calls. However, it is possible to change this behavior by using
OPTIMIZE and NOTINLINE declarations.
KCL does block compilation in a sense, but what KCL doesn't do is to
make any of the procedures inaccessible. They can be called by
procedures outside the file.
∂07-Feb-89 1341 Common-Lisp-Object-System-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 7 Feb 89 13:41:39 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA05101; Tue, 7 Feb 89 14:39:59 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00904; Tue, 7 Feb 89 14:39:57 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902072139.AA00904@defun.utah.edu>
Date: Tue, 7 Feb 89 14:39:55 MST
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY
To: Common-Lisp-Object-System@SAIL.Stanford.edu
Cc: CL-Compiler@SAIL.Stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Thu, 26 Jan 89 18:36:59 CST
Just a reminder -- at last month's meeting there was a comment that the
part of this proposal dealing with CLOS is "wrong". Can somebody please
supply more specifics about the complaint and/or suggest some alternate
wording? If I don't hear from anybody, the existing wording will remain.
-Sandra
-------
∂08-Feb-89 0836 CL-Compiler-mailer Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
Received: from ti.com by SAIL.Stanford.EDU with TCP; 8 Feb 89 08:36:10 PST
Received: by ti.com id AA01291; Wed, 8 Feb 89 10:33:21 CST
Received: from Kelvin by tilde id AA12640; Wed, 8 Feb 89 10:19:58 CST
Message-Id: <2811946753-4915749@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 8 Feb 89 10:19:13 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu, moon@stony-brook.scrc.symbolics.com,
Kolts@DSG.csc.ti.com
Subject: Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
In-Reply-To: Msg of Wed, 1 Feb 89 16:07:34 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
For the "current practice" section, the Explorer currently implements
proposal COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE; that's what we
settled on several years ago after trying it both ways. For your
information, following is the recollections of the person who was
working on that at the time.
------- Forwarded Message
Date: Tue, 7 Feb 89 18:00:49 CST
From: John Kolts <kolts@dsg.csc.ti.com>
Subject: Re: fasdumping symbols
To: David N Gray <Gray@DSG>
Cc: Kolts@DSG
In-Reply-To: Msg of Fri, 3 Feb 89 11:00:43 CST from David N Gray <Gray@DSG>
David,
My primary motivation was compile/load consistency. I thought it
was important that during loading all symbol references should resolve
to the same symbol as they would have during the compilation. If, for
instance, the packages used by *package* were different at compile time
than at load time, my approach would still intern the accessible symbols
in the "right" package during loading. Thus loading an XLD should
result in identical behavior regardless of changes to the package
structure in the load environment. Of course, such an approach means
that loading the XLD could give results incompatible with loading the
LISP file directly, but I felt that if behavior consistent with some
altered package structure was desired, the file should be recompiled, a
relatively small price to pay for the benefit of this consistency.
A related consideration was that remembering the home package seemed to
be important for proper macro expansion in certain cases.
What was apparent was that there were several defensible approaches,
none of which was obviously the absolutely right way to handle certain
pathological situations. Making the expected behavior explicit in a
standard is a good idea.
-John-
------- End of Forwarded Message
∂08-Feb-89 0851 CL-Compiler-mailer Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
Received: from ti.com by SAIL.Stanford.EDU with TCP; 8 Feb 89 08:51:04 PST
Received: by ti.com id AA01349; Wed, 8 Feb 89 10:49:17 CST
Received: from Kelvin by tilde id AA13042; Wed, 8 Feb 89 10:36:24 CST
Message-Id: <2811947745-4975339@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 8 Feb 89 10:35:45 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu, moon@stony-brook.scrc.symbolics.com
Subject: Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
In-Reply-To: Msg of Wed, 1 Feb 89 16:07:34 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> (a) If any top level form in a compiled file changes the value
> of *PACKAGE*, other than a SELECT-PACKAGE appearing as the first
> top-level form in the file, the results are unspecified.
There really shouldn't be anything wrong about using SELECT-PACKAGE
multiple times within a file as long as it is used at top level so that
the compiler knows that the current package is being changed.
A more troublesome situation which might be worth a warning is the use
of the "dangerous" package functions [CLtL p. 173]; if our compiler sees
a top-level call to SHADOW, SHADOWING-IMPORT, UNINTERN, or UNEXPORT, it
purges the affected symbols from the table of objects already dumped, so
that any subsequent references will be interned with the modified
package. We found this necessary to avoid some strange and unexpected
behavior.
∂08-Feb-89 0912 CL-Compiler-mailer Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 8 Feb 89 09:12:28 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA01630; Wed, 8 Feb 89 10:10:49 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00241; Wed, 8 Feb 89 10:10:44 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902081710.AA00241@defun.utah.edu>
Date: Wed, 8 Feb 89 10:10:42 MST
Subject: Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu, moon@stony-brook.scrc.symbolics.com
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Wed, 8 Feb 89 10:35:45 CST
> Date: Wed, 8 Feb 89 10:35:45 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> There really shouldn't be anything wrong about using SELECT-PACKAGE
> multiple times within a file as long as it is used at top level so that
> the compiler knows that the current package is being changed.
Actually, I agree with you. The problem has to do with the notion of
the "current package" that proposals CURRENT-PACKAGE and
REQUIRE-CONSISTENCY depend on. If the value of *PACKAGE* is allowed
to change throughout the file, which one is the "current package" that
is used to decide how to dump the symbols? Many compilers save up all
the symbols and dump them after the entire file has been processed.
Alternatively you could say that the "current package" is the value of
*PACKAGE* when the top-level form containing a reference to a
particular symbol was read in, or when the top-level form was actually
"processed" by the compiler (note that these are not the same). Plus,
you might end up having the same symbol referenced in several places,
with different values of *PACKAGE* in each place.
In my view, this confusion is a good reason for supporting proposal
HOME-PACKAGE.
> A more troublesome situation which might be worth a warning is the use
> of the "dangerous" package functions [CLtL p. 173]; if our compiler sees
> a top-level call to SHADOW, SHADOWING-IMPORT, UNINTERN, or UNEXPORT, it
> purges the affected symbols from the table of objects already dumped, so
> that any subsequent references will be interned with the modified
> package. We found this necessary to avoid some strange and unexpected
> behavior.
CLtL already warns about these functions being "dangerous" in several
places. I don't really think we need to reiterate that in this proposal.
-Sandra
-------
∂08-Feb-89 0934 CL-Compiler-mailer Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 8 Feb 89 09:34:28 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA26107; Wed, 8 Feb 89 09:35:18 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA05532; Wed, 8 Feb 89 09:31:53 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA15810; Wed, 8 Feb 89 09:34:42 PST
Date: Wed, 8 Feb 89 09:34:42 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8902081734.AA15810@clam.sun.com>
To: Gray@DSG.csc.ti.com, sandra%defun@cs.utah.edu
Subject: Re: issue COMPILE-FILE-SYMBOL-HANDLING, version 1
Cc: Kolts@DSG.csc.ti.com, cl-compiler@sail.stanford.edu,
moon@stony-brook.scrc.symbolics.com
Thanks for the info. This is similar to my thinking (as a one-time
package system implementor). In reality some compile-time bindings
do take place, so it seems best to bind the home package of the
symbol at compile-time also.
∂08-Feb-89 0954 CL-Compiler-mailer issue CONSTANT-CIRCULAR-COMPILATION, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 8 Feb 89 09:54:01 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA03605; Wed, 8 Feb 89 10:52:29 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00301; Wed, 8 Feb 89 10:52:25 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902081752.AA00301@defun.utah.edu>
Date: Wed, 8 Feb 89 10:52:24 MST
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 6
To: cl-compiler@sail.stanford.edu
Here's a new version of the writeup on this issue. Since nobody has
spoken up for proposal FLAG after our last round of discussion, I've
replaced it with a new proposal YES.
Forum: Compiler
Issue: CONSTANT-CIRCULAR-COMPILATION
References: Issue CONSTANT-COLLAPSING
Issue QUOTE-MAY-COPY
Category: CLARIFICATION, ADDITION
Edit History: V1, 07 Nov 1988, Sandra Loosemore
V2, 14 Nov 1988, Cris Perdue
V3, 12 Dec 1988, Sandra Loosemore (merge versions 1 and 2)
V4, 03 Jan 1989, Sandra Loosemore (add PRESERVE-SHARING-ONLY)
V5, 06 Jan 1989, Sandra Loosemore (minor wording changes)
V6, 08 Feb 1989, Sandra Loosemore (replace FLAG with YES)
Status: **DRAFT**
Problem Description:
CLtL does not specify whether constants containing circular or
recursive references may be compiled. It is also not clear whether
the compiler must preserve sharing of EQ substructures; that is, whether
subobjects that are EQ in the source code must remain EQ after being
compiled.
The proposals below apply to constants appearing in a file compiled by
COMPILE-FILE, which must inherently. If proposal
QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE passes, then the same constraints
would apply to all constants. The minimal scope over which sharing would
be required to be detected is over a single call to EVAL or COMPILE.
In the proposals that follow, "preserving EQness" means that
subobjects that are EQ in the source code must remain EQ after being
compiled; that is, things don't get "less EQ" after compilation.
(Note that coalescing of constants implies that things may get "more
EQ".)
Proposal CONSTANT-CIRCULAR-COMPILATION:NO
State that it is an error for an object containing a circular reference
to appear as a constant to be compiled. State that the compiler is not
required to preserve EQness of substructures.
Rationale:
This proposal would not require any existing implementation to change.
Disallowing portable programs from containing circular constants
allows compiled file loaders to use somewhat simpler implementation
strategies (for example, to build constants in a strict bottom-up
fashion).
Proposal CONSTANT-CIRCULAR-COMPILATION:PRESERVE-SHARING-ONLY
State that it is an error for an object containing a circular
reference to appear as a constant to be compiled. State that the
compiler is required to preserve EQness of substructures within a file
compiled with COMPILE-FILE.
Rationale:
Disallowing portable programs from containing circular constants
allows compiled file loaders to use somewhat simpler implementation
strategies (for example, to build constants in a strict bottom-up
fashion).
Some programs (such as PCL) have come to depend on COMPILE-FILE
preserving the EQness of uninterned symbols, and it is cleaner
to require sharing to be preserved in general instead of making
symbols be a special case. Requiring sharing to be preserved still
allows loaders to build constants bottom-up.
Proposal CONSTANT-CIRCULAR-COMPILATION:YES
State that objects containing circular references may legitimately
appear as constants to be compiled. State that the compiler is
required to preserve EQness of substructures within a file compiled
with COMPILE-FILE.
Rationale:
Users seem to expect this functionality, and some implementations
already provide it.
Current Practice:
A-Lisp preserves EQness of substructures (since it makes an effort to
collapse isomorphic structures) but signals an error if an attempt is
made to compile a circular constant. PSL and Utah Common Lisp both
get stuck in an infinite loop if an attempt is made to compile a
reentrant structure. The TI Explorer compiler is able to reproduce
recursive lists and arrays, but currently hangs in a loop on a
circular list. Neither the Explorer nor Symbolics Genera 7.x detects
EQness of list CDRs. Lucid handles circular constants correctly.
Franz uses a flag to control whether or not to attempt to detect
circular constants. KCL handles circular structures, but only detects
sharing of top-level structure (it does not traverse constants to look
for shared substructure).
Cost to implementors:
We know of no implementation that would have to change under proposal
NO.
For proposal YES, some implementations would require sweeping
changes; in some cases a completely different dumper/loader strategy
would have to be implemented.
The cost of proposal PRESERVE-SHARING-ONLY would fall somewhere in
between.
Cost to users:
The situation now is that programs which depend upon circularity or
sharing of substructure being preserved by the compiler are already
nonportable. Proposal NO simply formalizes the status quo. Proposal
YES would offer users functionality that is currently not portable.
Benefits:
An area of ambiguity in the language is removed.
Discussion:
The issue of compiler speed is largely a red herring on this issue;
the overhead of detecting circularities is generally quite small. The
main question is whether we should require some implementations to
completely redo their compiler/loader interface in order to support
circular constants.
It has been argued that any "serious" implementation will support
circular constants anyway, because of customer demand. However, since
there appears to be only one implementation (Lucid) that now
implements proposal YES in its full generality, perhaps the demand for
this feature is not really all that strong.
Earlier drafts of this writeup contained a proposal FLAG which would
have added a variable *COMPILE-CIRCLE*, similar to *PRINT-CIRCLE*.
However, there were unresolved problems about what would happen if the
value of this variable were altered within the file being compiled,
and it was generally agreed that this proposal didn't have any
particular advantages over proposal YES and just introduced
unnecessary hairiness.
-------
∂08-Feb-89 1043 CL-Compiler-mailer issue QUOTE-SEMANTICS, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 8 Feb 89 10:43:51 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA05613; Wed, 8 Feb 89 11:42:19 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00323; Wed, 8 Feb 89 11:42:16 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902081842.AA00323@defun.utah.edu>
Date: Wed, 8 Feb 89 11:42:15 MST
Subject: issue QUOTE-SEMANTICS, version 1
To: cl-compiler@sail.stanford.edu
I sent out this new writeup out a couple of weeks ago but haven't
received much response on it yet. Here it is again in case you've
forgotten about it. I'd like to send this out to X3J13 as soon as
possible, so let's try to get the bugs out of the writeup now.
If you have something you want added to the discussion section, let me
know.
I have one additional thing I'd like to raise on this issue, which is
how it relates to conformance requirements. To me it seems reasonable
that, if a program conforms to the standard, it ought to be possible
to compile it with COMPILE-FILE. Supposing we do not allow EVAL and
COMPILE to restrict what kinds of objects may appear as constats, is a
program in a file that contains a troublesome constant (like a quoted
stream object) a conforming program?
Forum: Compiler
Issue: QUOTE-SEMANTICS
Subsumes: Issue QUOTE-MAY-COPY
References: CLtL p. 55, 78, 86, 143
Issue CONSTANT-COLLAPSING
Issue CONSTANT-COMPILABLE-TYPES
Issue CONSTANT-CIRCULAR-COMPILATION
Category: CLARIFICATION
Edit History: V1, 22 Jan 1989, Sandra Loosemore
Status: **DRAFT**
Problem Description:
Is it permissible for COMPILE and EVAL to coalesce or copy constants?
Are there constraints upon what kinds of objects may appear as
constants in code processed by COMPILE or EVAL, similar to those for
COMPILE-FILE?
CLtL p86 states that (QUOTE <x>) simply returns <x>. On p55 it is
mentioned that the only self-evaluating forms that may be copied are
numbers or characters. It is also stated that an implementation is
permitted to collapse (or coalesce) EQUAL constants "appearing in code
to be compiled" (p78), which is defined to mean self-evaluating forms
or objects contained in a QUOTE form (without reference to whether the
form is processed by EVAL, COMPILE, or COMPILE-FILE).
Because of its nature as a file processor, COMPILE-FILE generally must
cause copies of constants to be constructed when the compiled code is
loaded. In a number of existing Lisp implementations, COMPILE also
causes constant objects to be copied and/or coalesced. There is also
at least one implementation where constants are copied by EVAL in some
circumstances.
Proposal QUOTE-SEMANTICS:NO-COPYING:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is not permitted; the resulting program
must reference objects that are EQL to the corresponding objects in
the source code. The constraints on what kinds of objects may appear
as constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.
Rationale:
This proposal is consistent with what many people think of as the
"traditional" semantics for QUOTE. It gives users maximum flexibility
about what kinds of objects may appear as constants.
Proposal QUOTE-SEMANTICS:COPYING-ALLOWED-BUT-NO-CONSTRAINTS:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted. Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime. Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.
Any object may validly appear as a constant in code processed by EVAL
or COMPILE. The constraints on what kinds of objects may appear as
constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.
Rationale:
This proposal is the most consistent with the semantics stated in CLtL.
It gives users maximum flexibility about what kinds of objects may
appear as constants.
Proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE:
State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted. Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime. Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.
The constraints on what kinds of objects may appear as constants
(described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply to EVAL and COMPILE as well as to
COMPILE-FILE.
Rationale:
This makes the rules for handling of constants consistent between
EVAL, COMPILE, and COMPILE-FILE. It gives implementors maximum
flexibility in handling constants in EVAL and COMPILE.
Current Practice:
Implementations in which COMPILE copies constants include PSL/PCLS and
Kyoto Common Lisp. In Lucid Common Lisp, constants are not normally
copied by COMPILE, but since COMPILE does coalesce constants, it may
cause QUOTE to return an object which is not EQL to the object which
appeared in the source code.
There is known to be at least one implementation where expanding the
DEFUN macro causes all constants in the body of the function to be
copied.
Cost to implementors:
Proposal NO-COPYING would involve a significant cost in those
implementations where constants are now copied or coalesced by EVAL
and COMPILE. Some implementations would also require substantial
changes to support proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS. The
aspect that is likely to cause the most problems is that, in some
implementations, the garbage collector assumes that constants
referenced in compiled code have been copied to read-only storage and
do not need to be scanned or relocated.
Proposal SAME-AS-COMPILE-FILE has no adoption cost above what is
required to support issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION.
Cost to users:
Proposals COPYING-ALLOWED-BUT-NO-CONSTRAINTS and SAME-AS-COMPILE-FILE
may break some existing programs that assume constants in code
processed by EVAL or COMPILE are always EQL to the corresponding
objects in the source code. Proposal SAME-AS-COMPILE-FILE may also
break existing programs that depend on referencing "undumpable"
constants in code processed by EVAL or COMPILE. In both cases,
however, the behavior is already nonportable. Both proposals would
permit implementations in which these programs now work to continue to
provide their existing behavior.
Benefits:
The semantics of QUOTE are clarified.
Discussion:
This issue subsumes issue QUOTE-MAY-COPY, which caused a very lengthy
debate on the cl-compiler mailing list.
Loosemore supports proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE,
since it requires essentially no conversion cost for implementors and
does not break any user programs that are not already nonportable.
-------
∂09-Feb-89 1126 CL-Compiler-mailer re: COMPILER-LET-CONFUSION, v3
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 9 Feb 89 11:26:35 PST
Date: Thu 9 Feb 89 11:24:33-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: re: COMPILER-LET-CONFUSION, v3
To: cl-compiler@SAIL.STANFORD.EDU
cc: kmp@SCRC-STONY-BROOK.ARPA, iim@ECLA.USC.EDU
Message-ID: <12469353505.28.IIM@ECLA.USC.EDU>
I originally sent this message about a week before the Hawaii meeting, but the
mailer bounced it. This describes the hack I came up with that Sandra was
refering to recently (I showed a copy of this message around in Hawaii).
kab
--------
> Date: Wed, 4 Jan 89 19:54 EST
> From: Glenn S. Burke <gsb@ALDERAAN.SCRC.Symbolics.COM>
>
> (defmacro with-new-frob (... &body body &environment env)
> `(macrovar-let ((frobs '((,name . ,data) ,@(macrovar 'frobs env))))
> ,@body))
Assuming the existance of SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM, I believe
this could be rewritten as
(defmacro with-new-form (... &body body &environment env)
`(symbol-macrolet ((frobs '((,name . ,data)
,@(multiple-value-bind (expansion macrop)
(macroexpand-1 'frobs env)
(when macrop expansion)))))
,@body))
Gosh, it seems like this technique just generally works. Is this really true?
Anybody want to blow holes in it (Kent, this means you)? If this does work,
then I think I can remove my objections to flushing COMPILER-LET.
kab
-------
∂10-Feb-89 1230 CL-Compiler-mailer issue COMPILED-FUNCTION-REQUIREMENTS, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Feb 89 12:30:17 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA24360; Fri, 10 Feb 89 13:28:38 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA01705; Fri, 10 Feb 89 13:28:35 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902102028.AA01705@defun.utah.edu>
Date: Fri, 10 Feb 89 13:28:34 MST
Subject: issue COMPILED-FUNCTION-REQUIREMENTS, version 3
To: cl-compiler@sail.stanford.edu
It didn't seem like proposal FLUSH had much support, so I've FLUSHed it. :-)
In its place I've added proposal TIGHTEN-COMPILE, which retains the
COMPILED-FUNCTION type but doesn't place quite as many restrictions on
it as proposal TIGHTEN. (This is the proposal I sketched out verbally
at the January meeting.) I also made a few minor clarifications to the
wording of proposal TIGHTEN.
Forum: Compiler
Issue: COMPILED-FUNCTION-REQUIREMENTS
References: CLtL p. 32, 76, 112, 143, 438-439
Issue FUNCTION-TYPE (passed)
Issue COMPILER-LET-CONFUSION
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue LOAD-TIME-EVAL (passed)
Category: CLARIFICATION
Edit History: V1, 3 Jan 1989 Sandra Loosemore
V2, 10 Jan 1989, Sandra Loosemore (additional proposal)
V3, 10 Feb 1989, Sandra Loosemore (new proposal)
Status: **DRAFT**
Problem Description:
There is confusion about what functions might be or must be of type
COMPILED-FUNCTION, and what attributes must be true of
COMPILED-FUNCTIONs. Is the distinction between COMPILED-FUNCTIONs and
other functions only one of representation, or can user programs infer
anything about COMPILED-FUNCTIONs? Are implementations required to
distinguish between compiled and non-compiled functions?
CLtL defines a COMPILED-FUNCTION as "a compiled code object". (Issue
FUNCTION-TYPE says only that COMPILED-FUNCTION must be a subtype of
FUNCTION.) Although it is not explicitly stated, CLtL implies that
compiled code must conform to certain rules; in particular, it states
that all macros are expanded at compile time, and specifies different
behavior for the COMPILER-LET and the EVAL-WHEN special forms
depending on whether they are interpreted or compiled.
The description of COMPILE in CLtL says that "a compiled-function object
[is] produced". It is not clear to everyone whether this implies that
COMPILED-FUNCTION-P must be true of such functions. CLtL says nothing
about whether functions defined in files compiled with COMPILE-FILE and
subsequently loaded must be of type COMPILED-FUNCTION.
Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN:
(1) Clarify that if a function is of type COMPILED-FUNCTION, the
following are guaranteed about the function:
- All macro calls appearing lexically within the function have
already been expanded and will not be expanded again when the
function is called. (See CLtL p. 143.)
- COMPILER-LETs nested lexically within the function will not bind
any variables when the function is called (CLtL p. 112).
- If the function contains lexically nested EVAL-WHENs, only the
LOAD (and not the EVAL) situation is applicable.
- If the function contains lexically nested LOAD-TIME-VALUE forms,
these have already been pre-evaluated and will not be evaluated
again when the function is called.
(2) Implementations are free to classify all functions as
COMPILED-FUNCTIONs, provided that all functions satisfy the criteria
listed in item (1). It is also permissible for interpreted FUNCTIONs
to satisfy the above criteria but not be distinguished as
COMPILED-FUNCTIONs.
(3) Clarify that COMPILE always produces an object of type
COMPILED-FUNCTION. Clarify that when functions are defined in a
file which is compiled with COMPILE-FILE, and the compiled file is
subsequently LOADed, objects of type COMPILED-FUNCTION result.
Rationale:
This proposal allows users to count on COMPILE and COMPILE-FILE always
producing objects that are COMPILED-FUNCTION-P.
It assigns some specific properties to compiled functions. Users would
be able to rely on any function which is of type COMPILED-FUNCTION having
really been (at least partially) compiled.
It also states what many people believe to be the minimum functionality
required of a compiler.
Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN-COMPILE:
(1) Clarify that functions produced by COMPILE, or defined in a file
that is compiled with COMPILE-FILE and then LOADed must satisfy
the same requirements listed in section (1) of proposal TIGHTEN.
(2) Clarify that COMPILE always produces an object of type
COMPILED-FUNCTION. Clarify that when functions are defined in a
file which is compiled with COMPILE-FILE, and the compiled file is
subsequently LOADed, objects of type COMPILED-FUNCTION result.
Rationale:
This proposal allows users to count on COMPILE and COMPILE-FILE always
producing objects that are COMPILED-FUNCTION-P.
It also states what many people believe to be the minimum functionality
required of a compiler.
However, it allows functions that have not been compiled also to be of
type COMPILED-FUNCTION. For implementations that do not use different
representations for interpreted and compiled functions, it would still
allow COMPILED-FUNCTION and FUNCTION to be synonymous, even if
interpreted functions do not satisfy the requirements for compilation.
Current Practice:
It appears that most implementations currently distinguish compiled
versus non-compiled functions on the basis of representation. It seems
unlikely that any implementation would have problems satisfying the
stated minimum requirements for compilation.
A-Lisp uses the same representation for both compiled and interpreted
functions and currently labels them both as COMPILED-FUNCTION, but the
implementation of COMPILED-FUNCTION-P could be easily fixed to
distinguish "real" compiled functions.
On the TI Explorer, the COMPILE function can return an object of
either type COMPILED-FUNCTION or LEXICAL-CLOSURE, where the latter
consists of two components -- an environment and a COMPILED-FUNCTION.
There is confusion about whether microcoded functions should be
considered compiled or not.
Cost to implementors:
Unknown, but probably small for either proposal. Proposal
TIGHTEN-COMPILE is probably most consistent with current practice.
Cost to users:
Probably minimal. Since the COMPILED-FUNCTION type specifier is
currently ill-defined, it is hard to imagine that existing programs
can portably rely on any interpretation of what it means that is
inconsistent with what is presented here.
Benefits:
The specification of what the compiler must do is made more explicit.
Discussion:
The FIXNUM and BIGNUM types were also defined in CLtL solely on the
basis of distinguished representations, and that this definition has
proved inadequate for just about all portable usages of these type
specifiers. Defining COMPILED-FUNCTION solely on the basis of
distinguished representation seems like a bad idea.
David Gray notes:
We make good use of the type COMPILED-FUNCTION in our implementation,
but all of the accessor functions for objects of that type are
non-standard, which makes me wonder if it might be best to just remove
this type from the standard along with BIGNUM.
One use of the COMPILED-FUNCTION type is in declarations. A-Lisp and
Lucid, for example, can compile FUNCALL more efficiently if it can be
determined that the function is of type COMPILED-FUNCTION. However,
in order for such declarations to be really useful, there should be a
way to construct an object which is guaranteed to be of type
COMPILED-FUNCTION. Both of the proposals presented require COMPILE
and COMPILE-FILE to construct compiled functions.
-------
∂10-Feb-89 1257 Common-Lisp-Object-System-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Feb 89 12:57:19 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA25181; Fri, 10 Feb 89 13:55:39 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA01721; Fri, 10 Feb 89 13:55:37 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902102055.AA01721@defun.utah.edu>
Date: Fri, 10 Feb 89 13:55:36 MST
Subject: Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Fri, 13 Jan 89 17:33:28 CST
> Date: Fri, 13 Jan 89 17:33:28 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> > Proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE:
> >
> > State that macro environment objects received with the &ENVIRONMENT
> > argument of a macro function have indefinite extent.
>
> That's fine for macro definitions, but this will not work for environments
> containing class definitions. The compiler needs to be able to know when
> those compile-time class definitions are no longer needed so that they can
> be unlinked from the class data structures.
>
> This issue has a strong relationship with issue
> SYNTACTIC-ENVIRONMENT-ACCESS since it proposes extending the use of
> environments in ways that would make anything other than
> MACRO-ENVIRONMENT-EXTENT:DYNAMIC difficult to retro-fit to existing
> implementations.
I am still trying to understand all of the implications of what CLOS
wants to do with macro expansion environments. To me, it seems like this
whole business would be difficult to retro-fit to existing implementations,
regardless of what we decide to do about the extent of macro environments.
My current mental picture of how this is supposed to work is that
compile-time environment objects are supposed to contain a pointer to
a database of all the class definitions. I don't see why the compiler
would need to unlink anything; when there are no longer any pointers
to the database, it would get "unlinked" automatically during garbage
collection, just like any other object, right?
-Sandra
-------
∂10-Feb-89 1326 CL-Compiler-mailer re: EVAL-WHEN-NON-TOP-LEVEL
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 10 Feb 89 13:26:07 PST
Date: Thu 9 Feb 89 11:27:36-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: re: EVAL-WHEN-NON-TOP-LEVEL
To: sandra%defun@CS.UTAH.EDU, JonL@LUCID.COM
cc: cl-compiler@SAIL.STANFORD.EDU, iim%ECLA@ECLC.USC.EDU
Message-ID: <12469354059.28.IIM@ECLA.USC.EDU>
Regarding our conversations during the Hawaii meeting: now that I have had
time to think about it and spent some time exploring the effects, I agree with
the proposal to make EVAL-WHEN not pass "top-level" through. I think this
gives us the following description for EVAL-WHEN.
When an EVAL-WHEN form is encountered by the interpreter, if the EVAL
sitiation is specified then the body of the form is processed as an implicit
PROGN. Otherwise, the interpreter treats the form as NIL.
The compiler processes an EVAL-WHEN form in two steps. First, if the COMPILE
situation is specified and the compiler processing is at "top-level", then
the body forms are evaluated in order (as if by EVAL). Second, if the LOAD
situation is specified then the body is processed as a non-top-level implicit
PROGN. If the LOAD situation is not specified then the compiler treats the
form as NIL.
This is a change, both from CLtL and from what we were proposing before, but I
think it does what we want.
kab
-------
∂10-Feb-89 1443 CL-Compiler-mailer re: EVAL-WHEN-NON-TOP-LEVEL
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 10 Feb 89 14:43:36 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA19081; Fri, 10 Feb 89 14:43:33 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA10653; Fri, 10 Feb 89 14:40:08 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA21581; Fri, 10 Feb 89 14:43:08 PST
Date: Fri, 10 Feb 89 14:43:08 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8902102243.AA21581@clam.sun.com>
To: IIM%ECLA@ECLC.USC.EDU, JonL@LUCID.COM, sandra%defun@CS.UTAH.EDU
Subject: re: EVAL-WHEN-NON-TOP-LEVEL
Cc: cl-compiler@SAIL.STANFORD.EDU, iim%ECLA@ECLC.USC.EDU
It seems to me that we really want two things out of EVAL-WHEN.
We want to be able to control compile- and load-time execution
of top level forms. Usually we want to be able to force something
to be defined or evaluated at compile time because it is needed
by some macro (or readmacro). Sometimes we want to control
compile- and load-time execution in other ways, too.
The second thing I claim we would really like to do with EVAL-WHEN
is to explain the behavior of forms such as defining macros in terms
of EVAL-WHEN (along with other Lisp code), for example explaining
DEFMACRO as similar to:
(eval-when (compile load eval)
(setf (macro-function ... ) ... ))
Are you compiler committee committee people in favor of these principles?
Notice that if you agree with these principles, you want
EVAL-WHEN to be defined in such a way that a lexically outer
EVAL-WHEN in effect overrides an inner one, so forms such as
(eval-when (compile)
(defmacro . . . ))
can mean "define the macro at compile-time only", and even
(eval-when (load)
(defmacro . . . ))
can mean "define the macro at load-time only".
∂10-Feb-89 1449 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
Received: from PORSCHE.SCRC.Symbolics.COM ([128.81.41.69]) by SAIL.Stanford.EDU with TCP; 10 Feb 89 14:49:27 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by PORSCHE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 868; Fri 10-Feb-89 17:12:57 EST
Date: Fri, 10 Feb 89 17:13 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: David N Gray <Gray@DSG.csc.ti.com>, cl-compiler@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8902102055.AA01721@defun.utah.edu>
Message-ID: <19890210221326.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 10 Feb 89 13:55:36 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
I am still trying to understand all of the implications of what CLOS
wants to do with macro expansion environments.
Resolving that is dependent on resolving EVAL-WHEN. You either already
have the Symbolics proposal for EVAL-WHEN, or will have it soon (I'm not
sure if Kent sent it yet). I think only Sandra will see this draft, the
mailing lists should see it shortly afterwards.
To me, it seems like this
whole business would be difficult to retro-fit to existing implementations,
regardless of what we decide to do about the extent of macro environments.
My opinion is that anything in CLOS that seems to depend on indefinite
extent for macro environments is broken and needs to be fixed. It's not
broken because of the environment extent, but for other reasons.
Thus I believe in dynamic extent for environments.
> Date: Fri, 13 Jan 89 17:33:28 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
> That's fine for macro definitions, but this will not work for environments
> containing class definitions. The compiler needs to be able to know when
> those compile-time class definitions are no longer needed so that they can
> be unlinked from the class data structures.
My current mental picture of how this is supposed to work is that
compile-time environment objects are supposed to contain a pointer to
a database of all the class definitions.
"pointer" is a key word that usually means you are thinking at too low
a level of abstraction. Also that mental picture may or may not be wrong,
depending on how we resolve how CLOS metaobjects work at compile time,
which depends on resolving EVAL-WHEN first.
I don't see why the compiler
would need to unlink anything; when there are no longer any pointers
to the database, it would get "unlinked" automatically during garbage
collection, just like any other object, right?
When Gray said "unlink" he was referring to the links between subclasses
and superclasses, not the links between names and objects.
∂10-Feb-89 1535 CL-Compiler-mailer Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Feb 89 15:34:33 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 537358; Fri 10-Feb-89 18:32:19 EST
Date: Fri, 10 Feb 89 18:32 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: CL-Compiler@SAIL.Stanford.EDU
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <890210183211.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Moon and I were not happy with the previous proposals on this issue, so
we wrote the following alternative proposal. This proposal was not an
overnight project -- it's the result of quite a bit of careful thought,
discussion and review. I'm pretty happy with the outcome. It seems to
deal nicely with some issues that have bugged me for a while. I hope that
other people will like it, too.
-----
Issue: EVAL-WHEN-NON-TOP-LEVEL
Forum: Compiler
References: EVAL-WHEN (CLtL pp69-70),
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CLARIFICATION/CHANGE
Edit History: 06-May-88, Version 1 by Sandra Loosemore
16-Dec-88, Version 2 by Loosemore (alternate direction)
30-Dec-88, Version 3 by Loosemore (minor wording changes)
07-Jan-89, Version 4 by Loosemore (update discussion)
09-Feb-89, Version 5 by Pitman and Moon (some major changes)
Status: For Internal Discussion
Problem Description:
The current description of how the compiler should handle EVAL-WHEN
only makes sense when it appears as a top-level form in the file being
compiled. Is it legitimate for EVAL-WHEN to appear in non-top-level
locations? Even if it is legitimate, what does it mean?
Another issue, referred to here as ``the EVAL-WHEN shadowing problem,''
is that some people have complained that shadowing the symbols EVAL,
COMPILE, or LOAD means that you have to also either shadow EVAL-WHEN
and define it to recognize the new symbol, or else you must resign
yourself to writing (EVAL-WHEN (... LISP:EVAL ...) ...),etc. all over.
While the goal here is not to solve this problem, it might be possible
to solve both problems at once.
Background/Analysis:
The proposal which follows was constructed with the following goals
in mind:
1. The lexical and dynamic environment for the EVAL-WHEN body should
be the same for each situation. That is, the body should ``mean
the same thing'' regardless of which situation is being processed.
2. The evaluation context for EVAL-WHEN should be the current
lexical environment.
3. At execution time, EVAL-WHEN should always return the result of
its last form if execution of the body occurred, or NIL if the
body was not executed.
4. If a top-level EVAL-WHEN has a LOAD keyword, its body should
inherit top-level-ness during normal processing. This permits the
use of (EVAL-WHEN (EVAL COMPILE LOAD) ...) at top-level to mean
simply "Do whatever would normally be done for this body, but
also do something at compile time." This, in turn, will later be
the key to allowing defining forms to be usefully described in
terms of EVAL-WHEN.
5. Non-top-level expressions should have no effect until they are
executed. This is the key to making sure that any necessary
environment is present. Since the COMPILE keyword forces effects
to occur earlier than execution time, it follows from this that
any correct solution must not allow the COMPILE keyword to have
an effect at other than top-level.
To accomplish these goals, we formulated the following model:
The purpose of EVAL-WHEN is to accomodate the fact that some of the
semantic processing of an expression may usefully be partitioned
between compile time and run time in some circumstances.
(EVAL-WHEN (EVAL) <code>)
describes a general technique for accomplishing some particular goal
at normal program execution time. However, the pair of expressions
(EVAL-WHEN (COMPILE) <code-A>)
(EVAL-WHEN (LOAD) <code-B>)
can be used to describe an alternate technique for implementing part
of the effect (A) at compile-time, and part of the effect (B) at
load-time.
Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL):
Replace the description of EVAL-WHEN with the following:
EVAL-WHEN ({situation}*) {form}* [Special Form]
The body of an EVAL-WHEN form is processed as an implicit PROGN, but
only in the situations listed. Each SITUATION must be a symbol,
either COMPILE, LOAD, or EVAL.
The use of COMPILE and LOAD controls whether and when processing
occurs for top-level forms. The use of EVAL controls whether
processing occurs for non-top-level forms.
The EVAL-WHEN construct may be more precisely understood in terms of
a model of how the file compiler, COMPILE-FILE, processes forms in a
file to be compiled. This model is totally general and is also used
for other processors (such as the runtime compiler, COMPILE, and the
evaluator, EVAL), but many of the cases which are necessary to explain
the file compiler do not come up in other processors.
Successive forms are read from the file by the file compiler using
READ. These top-level forms are normally processed in what we call
`not-compile-time' mode. There is one other mode, called
`compile-time-too' mode, which can come into play for top-level
forms. The EVAL-WHEN special-form is used to annotate a program
in a way that allows the program doing the processing to select
the appropriate mode.
Processing of Common Lisp forms to be executed or compiled works
as follows:
If this is a top-level form in the file compiler,
then if the form is an EVAL-WHEN,
then if {both the COMPILE and LOAD situations are specified},
or {{both the EVAL and LOAD situations are specified}
and {the mode is compile-time-too}},
then process (PROGN . body) as a top-level form
in compile-time-too mode,
else if the LOAD situation is specified,
then process (PROGN . body) as a top-level form
in not-compile-time mode,
else if {the COMPILE situation is specified},
or {{the EVAL situation is specified}
and {the mode is compile-time-too}},
then evaluate the form (PROGN . body),
;; {neither COMPILE nor LOAD}, and
;; {not EVAL in compile-time-too mode}
else do nothing,
;; a top-level form in the file compiler that is not an EVAL-WHEN
else if in compile-time-too-mode,
then evaluate the form and then perform normal compiler
processing of the form as a top-level form,
;; not-compile-time mode
else perform normal compiler processing of the form as a
top-level form,
;; not a top-level form in the file compiler: one of {in the interpreter},
;; or {in COMPILE}, or {in the file compiler not at top level}
else if the form is an EVAL-WHEN,
then if the EVAL situation is specified,
then process (PROGN . body)
else process NIL
;; not an EVAL-WHEN
else process the form normally
(PROGN . body) designates a form constructed by extracting the
body forms from another form (EVAL-WHEN (situation...) . body).
"Process" means to perform macroexpansion and the actions indicated by
this decision tree. COMPILE-FILE "processes" each form read from the
file as a top-level form in not-compile-time mode (i.e., with
compile-time-too mode off). COMPILE and EVAL process each form
they encounter as a normal form (i.e., a form that is not a top-level
form); COMPILE-FILE does the same for non-top-level forms.
"Evaluate" means to execute the form in the lexical environment in
which the EVAL-WHEN appeared and in the compiler's executing dynamic
environment.
"Normal compiler processing" means to process a top level form in
the defined fashion for compilers, e.g. compiling function definitions.
"Normal processing" means to execute a form if this is EVAL or
to compile the form if this is COMPILE or COMPILE-FILE.
Clarifications/Consequences:
The following effects are logical consequences of the above proposal:
* It is never the case that the execution of a single EVAL-WHEN
expression will execute the body code more than once.
* The keyword `EVAL' is a misnomer because execution of
the body need not be done by EVAL. In compiled code, such as
(DEFUN FOO () (EVAL-WHEN (EVAL) (PRINT 'FOO)))
it is permissible (even desirable) for the call to PRINT to be compiled.
* Macros intended for use in top-level forms should arrange for all
side-effects to be done by the forms in the macro expansion.
The macro-expander itself should not do the side-effects.
Wrong: (defmacro foo ()
(really-foo)
`(really-foo))
Right: (defmacro foo ()
`(eval-when (compile eval load) (really-foo)))
Adherence to this convention will mean that such macros will behave
intuitively when placed in non-top-level positions.
* Placing a variable binding around an EVAL-WHEN reliably captures the
binding because the `compile-time-too' mode cannot occur (because
introducing a variable binding would mean we were not at top level).
For example,
(LET ((X 3))
(EVAL-WHEN (EVAL LOAD COMPILE) (PRINT X)))
will print 3 at execution [load] time, and will not print anything at
compile time. This is important so that expansions of DEFUN and
DEFMACRO can be done in terms of EVAL-WHEN and can correctly capture
the lexical environment.
(DEFUN BAR (X) (DEFUN FOO () (+ X 3)))
might expand into
(DEFUN BAR (X)
(PROGN (EVAL-WHEN (COMPILE)
(COMPILER::NOTICE-FUNCTION-DEFINITION 'FOO '(X)))
(EVAL-WHEN (EVAL LOAD)
(SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))))
which would be treated the same as
(DEFUN BAR (X)
(SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))
by the above rules.
* The following table is an alternate way of describing the proposed actions:
Level COMPILE LOAD EVAL C.t.t. Action Level C.t.t.
top Yes Yes -- -- Process (PROGN body...) top Yes
top No Yes Yes Yes Process (PROGN body...) top Yes
top No Yes Yes No Process (PROGN body...) top No
top No Yes No -- Process (PROGN body...) top No
top Yes No -- -- Evaluate (PROGN body...)
top No No Yes Yes Evaluate (PROGN body...)
top No No Yes No do nothing
top No No No -- do nothing
top not an eval-when Yes Evaluate it and then
perform normal compiler processing
top not an eval-when No Normal compiler processing
normal -- -- Yes -- Process (PROGN body...) normal
normal -- -- No -- Process NIL normal
normal not an eval-when -- Normal processing
"C.t.t." is an abbreviation for compile-time-too mode
"--" means don't-care
Test Cases:
;; #1: The EVAL-WHEN in this case is not at top-level, so only the EVAL
;; keyword is considered. At compile time, this has no effect.
;; At load time (if the LET is at top level), or at execution time
;; (if the LET is embedded in some other form which does not execute
;; until later) this sets (SYMBOL-FUNCTION 'FOO1) to a function which
;; returns 1.
(LET ((X 1))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO1) #'(LAMBDA () X))))
;; #2: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting
;; (SYMBOL-FUNCTION 'FOO2) to a function which returns 2.
(EVAL-WHEN (EVAL LOAD COMPILE)
(LET ((X 2))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO2) #'(LAMBDA () X)))))
;; #3: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting the
;; function cell of FOO3 to a function which returns 3.
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO3) #'(LAMBDA () 3)))
;; #4: This always does nothing. It simply returns NIL.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (COMPILE)
(PRINT 'FOO4)))
;; #5: If this form occurs at top-level of a file to be compiled, FOO5 is
;; printed at compile time. If this form occurs in a non-top-level
;; position, nothing is printed at compile time. Regardless of context,
;; nothing is ever printed at load time or execution time.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (EVAL)
(PRINT 'FOO5)))
Rationale:
This is compatible with any guarantees made by CLtL, and extends the
behavior usefully to non-top-level situations.
This gives a useful meaning to EVAL-WHEN that supports useful and
predictable behavior if defining macros are used in a non-top-level
situation.
Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS):
As in GENERALIZE-EVAL, but rename the EVAL keyword to :EXECUTE,
the COMPILE keyword to :COMPILE-TOPLEVEL, and LOAD keyword to
:LOAD-TOPLEVEL.
Deprecate the use of keywords EVAL, COMPILE, and LOAD to EVAL-WHEN.
For compatibility, they are supported in EVAL-WHEN
at top-level, but their meaning is not defined elsewhere.
Rationale:
The fact that the situation keywords chosen are not the same as
those now used means that the change can be added in a way that
is truly upward compatible (not only with CLtL but with existing
practice in implementations which have chosen to extend or `clarify'
the definition given in CLtL) since the meaning of EVAL, COMPILE,
and LOAD in non-top-level situations (which was never spelled
out in CLtL) can legitimately differ from the meaning of these
new keywords.
Using other names and/or the keyword package for the names of
situations solves the EVAL-WHEN shadowing problem.
The name `execute' does not promote the confusion that the body of an
EVAL-WHEN must be executed only in the evaluator. It also does not
promote the confusion that the body of an EVAL-WHEN, regardless of when
executed, must run interpreted.
The names `compile-toplevel' and `load-toplevel' emphasize the fact
that these cases are not interesting in non-top-level positions.
Current Practice:
In Symbolics Genera, the interpreter permits EVAL-WHEN in non-top-level
positions in a way that is compatible with this proposal but both the
COMPILE and COMPILE-FILE functions complain about EVAL-WHEN in a
non-top-level position.
IIM describes its EVAL-WHEN as
(defmacro eval-when (situations &body body &environment env)
(if (not (compiler-environment-p env))
(when (member 'eval situations) `(progn ,@body))
(progn
(when (member 'compile situations)
(if (compiler-at-top-level-p env)
(mapc #'eval body)
(warn "Top-level form encountered at non-top-level.")))
(when (member 'load situations) `(progn ,@body)))))
Cost to Implementors:
The actual change to EVAL-WHEN in both cases is probably fairly
localized and straightforward to make in most or all implementations.
The second-order costs of proposal GENERALIZE-EVAL will vary depending
on whether existing implementations have extended the definition of
EVAL-WHEN in incompatible ways. If an implementation has made such
extensions, there may be user and system code which depends on them
and the cost of converting that code may be non-trivial. There is
presumably also documentation impact.
Proposal GENERALIZE-EVAL-NEW-KEYWORDS avoids most or all of the
second-order costs of proposal GENERALIZE-EVAL.
Cost to Users:
Technically, none. Either proposal is technically upward compatible
with CLtL.
Proposal GENERALIZE-EVAL might force some extended implementations to
change incompatibly. As such, some users who depend on
implementation-dependent extensions might have to adjust their code
somewhat to deal with those changes.
Proposal GENERALIZE-EVAL-NEW-KEYWORDS does not force implementations
to change incompatibly, so has no forced impact on users.
Cost of Non-Adoption:
EVAL-WHEN is a mess. Using it as the low-level substrate into which
defining macros should expand, and guaranteeing any predictable effects
of those macros in non-top-level situations is currently difficult and
would continue to be so in the absence of some resolution on this issue.
Benefits:
The costs of non-adoption would be avoided: it would be possible to
use EVAL-WHEN in many situations where it cannot currently be used
reliably.
The portability of many existing tools which use EVAL-WHEN internally
in macros will be enhanced.
Aesthetics:
This generalization of the meaning makes the purpose and uses of
EVAL-WHEN less mysterious. In that sense, aesthetics are simplified
somewhat.
Discussion:
Pitman and Moon don't care whether we say `top level,' `top-level,' or
`toplevel.' The spelling choices in this writeup are arbitrary. If
necessary, the proposal GENERALIZE-EVAL-NEW-KEYWORDS could be amended
to propose :COMPILE-TOP-LEVEL, etc.
Pitman, Moon, and Bob Laddaga (a Symbolics Cloe implementor) support
both of these proposals. Pitman and Laddaga have a preference for
GENERALIZE-EVAL-NEW-KEYWORDS. Moon is neutral about which should be
preferred.
∂10-Feb-89 1827 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Feb 89 18:26:59 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA03715; Fri, 10 Feb 89 19:25:26 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA01938; Fri, 10 Feb 89 19:25:19 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902110225.AA01938@defun.utah.edu>
Date: Fri, 10 Feb 89 19:25:18 MST
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU, Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 10 Feb 89 18:32 EST
My initial reaction to this proposal is that it makes the behavior of
EVAL-WHEN -- particularly its nesting behavior -- even harder to
understand than the description in CLtL. The proposal does seem to
solve the problem but it took me quite a while even to verify that
this proposal is compatible with CLtL for top-level EVAL-WHENs and
step through the examples to see how they work.
I think it would be helpful if the writeup included an analysis to
summarize the nesting behavior:
For a <body> nested inside of several top-level EVAL-WHENs:
(1) Normal interpreter of <body> happens when -all- of
the nested EVAL-WHENs specify the EVAL situation.
(2) Normal compiler processing of <body> happens when -all- of the
nested EVAL-WHENs specify the LOAD situation.
(3) Compile-time evalution of <body> happens when -one- of the
EVAL-WHENs specifies the COMPILE situation. If that EVAL-WHEN
also specifies LOAD, then -all- of the ones nested inside of
it must specify either COMPILE or EVAL. If that EVAL-WHEN
does not specify LOAD, then -all- of the ones nested inside of
it must specify the EVAL situation.
The asymmetry of the last item bothers some people. In particular,
some people write
(eval-when (load)
(defmacro foo ...))
thinking that this would make FOO defined only at load time and not at
compile time. I think the writeup should at least mention that this
doesn't work, and also provide a rationale for why it shouldn't. This
is really the only part of the behavior this proposal specifies that
gives me any problems (my other complaints are just with it being hard
to understand).
Unless this new proposal has overwhelming support, I think I'd like to
continue to pursue the ideas we were developing earlier and present
both proposals. The proposal from Version 4 was certainly much easier
to understand and I think it would be much easier to tinker with the
nesting behavior it specifies than what Version 5 specifies. One
thing I'd like to do in any further revisions to Version 4 is to use
terms that are not as loaded as "top-level" and "non-top-level" to
describe what EVAL-WHEN should or shouldn't pass through, perhaps
something like "visible" and "shielded".
So, let's hear from some of the rest of you. Are you all happy with
this proposal or would you like to see something simpler?
-Sandra
-------
∂12-Feb-89 1343 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Feb 89 13:43:15 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 537728; Sun 12-Feb-89 16:40:35 EST
Date: Sun, 12 Feb 89 16:40 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: sandra%defun@cs.utah.edu
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU,
Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8902110225.AA01938@defun.utah.edu>
Message-ID: <890212164017.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
I believe your passion for understanding the nesting behavior to be very
dangerous. First and foremost, the job of EVAL-WHEN should be to have a
contract where you can understand it at any given level. If you write
each level with a proper understanding of things, the nesting behavior
will follow.
I want to support definitions like the following:
(DEFMACRO DEFMACRO (NAME BVL &BODY FORMS)
`(PROGN (EVAL-WHEN (COMPILE)
(COMPILER::NOTICE-DEFMACRO ',NAME ',BVL ',FORMS))
(SETF (MACRO-FUNCTION ',NAME) #'(LAMBDA (FORM ENV) ...))))
(DEFMACRO DEFUN (NAME BVL &BODY FORMS)
`(PROGN (EVAL-WHEN (COMPILE)
(COMPILER::NOTICE-DEFUN ',NAME ',BVL ',FORMS))
(SETF (SYMBOL-FUNCTION ',NAME) #'(LAMBDA ...))))
(DEFMACRO DEFCLASS (NAME SUPERIORS SLOTS &REST OPTIONS)
`(PROGN (EVAL-WHEN (COMPILE)
(COMPILER::DEFCLASS-1-A ...))
(EVAL-WHEN (LOAD)
(COMPILER::DEFCLASS-1-B ...))
(EVAL-WHEN (EVAL)
(COMPILER::DEFCLASS-2 ...))
',NAME))
or
(DEFMACRO DEFCLASS (NAME SUPERIORS SLOTS &REST OPTIONS)
`(PROGN (EVAL-WHEN (COMPILE EVAL)
(COMPILER::DEFCLASS-A ...))
(EVAL-WHEN (LOAD EVAL)
(COMPILER::DEFCLASS-B ...))
',NAME))
All I have to do in order to write such definitions is to know what each of
the keywords means:
LOAD says I want code run at top-level when loading.
COMPILE says I want code run at top-level when compiling.
EVAL says I want code run in embedded code.
That's all I have to know to -write- an EVAL-WHEN. The rest of the rules
for how to process an EVAL-WHEN don't affect how I -write- an EVAL-WHEN,
they just take care of assuring that other people who wrote an EVAL-WHEN
using those same rules don't have their model interfered with.
For example, it doesn't matter that
(EVAL-WHEN (COMPILE) (EVAL-WHEN (COMPILE) ...))
doesn't execute anything. The reason is that you probably never really
right this. Probably what really happens is Person 1 writes:
(DEFMACRO FOO () `(EVAL-WHEN (COMPILE) ...))
and Person 2 writes:
(EVAL-WHEN (COMPILE) (FOO))
Now all that's important is that Person 1 has asked himself the question
"Should FOO do anything when in a non-top-level position?" If he has answered
"Yes" to that, then he has made an extremely obvious programming error, and
no complicated reasoning about nested EVAL-WHEN's is needed to notice it.
If he has answered "No", then he presumably has a good reason. Then we have
to ask, did the person implementing "FOO" document that the form was legitimate
anywhere or only at top-level or what? If he documented that FOO was appropriate
to use anywhere, and he still used only the COMPILE option, then he must have
somehow proven to himself that the contract of FOO could be satisfied without
any work in some circumstances. Now the only remaining question is, did the
user of FOO read and use that documentation properly. Since we've agreed that
the doc says he could use it anywhere, then regardless of what
(EVAL-WHEN (COMPILE) (EVAL-WHEN (COMPILE) ...))
-does-, we know that it is doing what is intended.
A computer linguist at MIT, Bill Martin, once said in class that the
purpose of language syntax is not to enable you to say what was
plausible but to say what is not. If all you wanted to say was the things
that were obvious, you'd just write down a lot of words and assume that they
had their obvious relation. "FOOD EAT JOHN" would mean "John eats food"
and not "Food eats John." We have syntax rules to allow you to say the
latter just in case that's what you really meant.
The rules we've suggested produce nice nesting behaviors for things like
the following. I would say that in my experience, none of these things are
commonplace, yet they are all legitimate things to want to say. I think the
rules we've offered (and the definitions I've offered above which use those
rules) lead to -extremely- intuitive readings of all of these expressions...
(DEFUN FOO (X) (DEFUN BAR (Y) (+ X Y)))
defines a function FOO which when called defines a function BAR which
adds the value that was given to FOO to the value that was given to BAR.
(DEFUN FOO (X) (DEFMACRO BAR (Y) `'(FOOBAR ,X ,Y)))
defines a function FOO which when called defines a macro BAR which
returns a list of the three things: FOOBAR and the original arguments
to FOO and BAR.
(LET ((SOMETHING (LIST A B C)))
(DEFMACRO ZAP () `',SOMETHING))
defines a macro ZAP which returns the value SOMETHING. This macro has no
effect at compile time (although it can be subsequently loaded into the
compiler) because the compiler cannot know what the runtime value of
SOMETHING is.
(EVAL-WHEN (EVAL COMPILE LOAD)
(LET ((SOMETHING (LIST A B C)))
(DEFMACRO ZAP () `',SOMETHING)))
is like above but defines the macro in a way that is also visible to the
compiler.
I have to say that I find all of these nesting behaviors to be -extremely-
intuitive (in addition to being really the only acceptable ones). They
follow quite naturally from our definition of EVAL-WHEN and not from any
previous suggestion of how to rationalize EVAL-WHEN that I've seen.
∂12-Feb-89 1613 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Feb 89 16:13:18 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA02575; Sun, 12 Feb 89 17:11:40 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02791; Sun, 12 Feb 89 17:11:17 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902130011.AA02791@defun.utah.edu>
Date: Sun, 12 Feb 89 17:11:16 MST
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.Stanford.EDU,
Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Sun, 12 Feb 89 16:40 EST
I don't have any quibble with the behavior of the examples you cite.
However, you still haven't said anything to justify the behavior of
your proposal under example *I* cited in my previous message, namely,
why
(eval-when (load)
(defmacro foo ...))
should cause FOO to be defined in the compile-time environment even when
the user explicitly specified that the macro only needs to be defined at
load time.
Basically, the problem with the nesting behavior specified by your
proposal and by CLtL is that it provide for any way for the programmer
"turn off" the compile-time behavior of any of the various defining
macros like DEFMACRO, or of nested EVAL-WHENs. The proposal we were
working on before would make the behavior of the COMPILE situation
analagous to that of the EVAL and LOAD situations: if an outer
EVAL-WHEN doesn't specify the situation, then its body is ignored
under the context that pays attention to that situation, even if it
contains nested EVAL-WHENs that -do- specify that situation.
If there were a simple fix to your proposal that would change only
this aspect of the nesting behavior, I'd go ahead and propose that.
But to me it seems like you would have to introduce another state
variable (called NEVER-COMPILE-TIME-TOO or something like that), to
indicate whether the COMPILE situation should be ignored, and things
would get even more complicated. On the other hand, this nesting
behavior falls right out of the other proposal.
Incidentally, RAM's old "Compiler Proposal #3" proposed making a
similar change to the nesting behavior of EVAL-WHEN. Although he
would have replaced EVAL-WHEN with three new special forms, the one
corresponding to (LOAD EVAL) also inhibited any compile-time
evaluation of subforms.
-Sandra
-------
∂12-Feb-89 1827 Common-Lisp-Object-System-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Feb 89 18:26:21 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA03819; Sun, 12 Feb 89 19:21:55 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02883; Sun, 12 Feb 89 19:20:31 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902130220.AA02883@defun.utah.edu>
Date: Sun, 12 Feb 89 19:20:29 MST
Subject: Re: issue MACRO-ENVIRONMENT-EXTENT, version 1
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>,
David N Gray <Gray@DSG.csc.ti.com>, cl-compiler@SAIL.STANFORD.EDU,
common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 10 Feb 89 17:13 EST
Having seen the new proposal for EVAL-WHEN, I still don't have any idea
why the extent of macro environment objects depends on it. Can you
explain the connection?
Also, I don't think anybody is arguing for requiring environments to
have indefinite extent on the grounds that CLOS requires it. (The
argument is that it's generally useful and for general symmetry with
every other kind of Lisp data object having indefinite extent.) Just
the opposite -- David Gray's question was whether that requirement
would complicate the implementation of CLOS.
At the January meeting, Gregor made a verbal suggestion that perhaps
implementations ought to be allowed to support only dynamic extent, but
that we should add a function to make a copy of the environment object
which would have indefinite extent. If the problem is indeed that
certain things must be "unlinked" at the end of compilation, it
doesn't seem like this would solve the problem.
-Sandra
-------
∂13-Feb-89 1041 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by SAIL.Stanford.EDU with TCP; 13 Feb 89 10:41:43 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by Riverside.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 315381; Mon 13-Feb-89 13:39:11 EST
Date: Mon, 13 Feb 89 13:39 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: sandra%defun@cs.utah.edu
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU,
Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8902130011.AA02791@defun.utah.edu>
Message-ID: <890213133923.8.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Sun, 12 Feb 89 17:11:16 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
you still haven't said anything to justify the behavior of your proposal
under example *I* cited in my previous message, namely, why
(eval-when (load)
(defmacro foo ...))
should cause FOO to be defined in the compile-time environment even when
the user explicitly specified that the macro only needs to be defined at
load time.
Among other things, because it is incompatible with CLtL. p70 says:
If the situation LOAD is specified
then if the situation COMPILE is also specified
then ...
else process each of the forms in the body in not-compile-time mode.
`not-compile-time' mode must see DEFMACRO because the previous page says that
all top-level forms are defaultly processed in not-compile-time mode, which
means that DEFMACRO is normally noticed by the compiler when in that mode.
By the way, even before this issue came up, I would have told you that if you
really wanted macros that were visible only at load time and not at
compile time, the thing would be to put them in a separate file and load
then when you really needed them. Independently of any discussion of
EVAL-WHEN, I believe that to be the right answer to this problem.
Getting back to EVAL-WHEN, though, our semantics allow you to keep something
from being `noticed' by the compiler by just putting it in a non-top-level
position.
(LET () (DEFMACRO FOO ...))
is the easiest way to do that right now, but you can also write:
(DEFUN INIT ()
(DEFMACRO ...)
(DEFMACRO ...) ...)
(INIT)
Also, as a matter of pragmatics, I find that it is -extremely- rare to
want DEFMACRO to not be seen at compile time but rather only to be seen at
load time. If it had been desirable, it would have been easy to design a
form like DEFMACRO that did what you suggest. You can define one yourself
by writing something like:
(defmacro load-time-defmacro (name bvl &body forms)
`(progn (setf (macro-function ',name) #'(lambda (form env) ...))
',name))
or (defmacro load-time-defmacro (name bvl &body forms)
`(let () (defmacro ,name ,bvl ,@forms)))
... Basically, the problem with the nesting behavior specified
by your proposal and by CLtL is that it provide for any way for the
programmer
"does not" ? -------------------↑
"turn off" the compile-time behavior of any of the various defining
macros like DEFMACRO, or of nested EVAL-WHENs.
I don't agree that this is something that is ever a remarkably interesting
thing to want. Can you sketch a concrete example that demonstrates it as
something that is both useful and not trivially solvable by any of the above
mechanisms?
Finally, while I'm thinking about it, let me retroactively add another design
goal for EVAL-WHEN which I had when I was working on it but never ended up
verbalizing:
COMPILE must be meaningful in EVAL-WHEN if and only if LOAD is meaningful.
[If this is not so, it becomes impossible to reliably split a task in half,
with half the work being done by an (EVAL-WHEN (COMPILE) ...) and the
other half being done by (EVAL-WHEN (LOAD) ...).]
∂16-Feb-89 0911 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Feb 89 09:11:27 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA04037; Thu, 16 Feb 89 10:09:36 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05504; Thu, 16 Feb 89 10:09:30 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902161709.AA05504@defun.utah.edu>
Date: Thu, 16 Feb 89 10:09:28 MST
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.Stanford.EDU,
Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Mon, 13 Feb 89 13:39 EST
I'm aware that the nesting behavior in your new proposal is the same
as what is described in CLtL. Some people, however, have said that
they think the behavior described in CLtL is "broken". If those
people are willing to stop complaining about it, then I am too. But I
think that the writeup should at least make some mention of the
problem, even if it doesn't propose to fix it.
For current practice, as far as I can make out neither KCL nor Lucid
will make macro definitions available to the compiler when they are
wrapped inside an (EVAL-WHEN (LOAD) ...). (Neither of these
implementations uses EVAL-WHEN in the expansion of DEFMACRO.)
As for why one would want to suppress the compile-time magic of
defining macros: I've mostly run into the problem in cross-compilation
situations. DEFCONSTANT is probably more of a problem than DEFMACRO
in this respect. I agree that the situation is fairly rare, though.
Moving on to one other aspect of the new proposal, does anybody have
any comments on changing the meaning of the EVAL situation from "in
the interpreter" to "at execution time"? This does seem to solve the
problem of what to do in compiled-only implementations, at least.
-Sandra
-------
∂16-Feb-89 0949 CL-Compiler-mailer pending issues
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Feb 89 09:49:18 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA05223; Thu, 16 Feb 89 10:47:31 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05552; Thu, 16 Feb 89 10:47:29 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902161747.AA05552@defun.utah.edu>
Date: Thu, 16 Feb 89 10:47:27 MST
Subject: pending issues
To: cl-compiler@sail.stanford.edu
Just a reminder that we have less than a month left in which we are
supposed to resolve all of our pending issues. (Issues are supposed
to be mailed to X3J13 by March 15 to meet the 2-week deadline.) Things
have been rather dead on this mailing list lately. Does this really
mean that all of you are perfectly happy with the latest versions of
the proposals that have been sent around?
According to my notes, there has been no discussion at all on the
following issues since the latest versions of the writeups were mailed
out.
COMPILER-DIAGNOSTICS (V9, 26 Jan 1989)
COMPILER-VERBOSITY (V6, 26 Jan 1989)
CONSTANT-CIRCULAR-COMPILATION (V6, 08 Feb 1989)
QUOTE-SEMANTICS (V1, 22 Jan 1989)
COMPILED-FUNCTION-REQUIREMENTS (V3, 10 Feb 1989)
Let's get moving, folks...
-Sandra
-------
∂16-Feb-89 1016 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Feb 89 10:16:08 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 540451; Thu 16-Feb-89 13:10:01 EST
Date: Thu, 16 Feb 89 13:09 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: sandra%defun@cs.utah.edu
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU,
Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8902161709.AA05504@defun.utah.edu>
Message-ID: <890216130938.3.KMP@BOBOLINK.SCRC.Symbolics.COM>
I'll add the Current Practice items you mentioned.
If you are willing to object to the current definition of EVAL-WHEN for
top-level use (and to say why) or if you can find someone who will do so
in first person, I'll be happy to add commentary. [I found myself saying
``Objection, your honor. Hearsay.'' as I read your note. I've been
watching a lot of Perry Mason lately...] Otherwise, I can add a note
saying there have been vague grumblings of discontent, but I don't think
anyone will find that a compelling reason to change things; for all
anyone knows the thing we are changing are not the targets of that
discontent, and we'll only be making things worse -- not better.
As to cross-compilation, I've said I don't think you can write a fully
correct cross compiler for Common Lisp anyway -- and not for any reason
that has to do with EVAL-WHEN. I can expand on why privately if anyone
challenges me; this is not the right forum. However, given that I
believe this, I also believe that worrying about cross-compilation in
order to decide how EVAL-WHEN should work is effectively mis-guided.
∂16-Feb-89 1019 CL-Compiler-mailer issue COMPILER-LET-CONFUSION
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Feb 89 10:17:53 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA06300; Thu, 16 Feb 89 11:09:43 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05566; Thu, 16 Feb 89 11:08:27 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902161808.AA05566@defun.utah.edu>
Date: Thu, 16 Feb 89 11:08:26 MST
Subject: issue COMPILER-LET-CONFUSION
To: cl-compiler@sail.stanford.edu
Cc: kmp@stony-brook.scrc.symbolics.com, iim@ecla.usc.edu
To summarize what has [not] been happening on this issue:
Kent Pitman had prepared a new proposal, REPAIR, to go along with the
older ELIMINATE proposal just before the January meeting. This writeup
has not been distributed to X3J13.
At the meeting, Kim Barrett showed me a technique for using
SYMBOL-MACROLET as a replacement for COMPILER-LET that (to me) appears
to satisfy Kent's requirements. It relies on using MACROEXPAND to get
the "value" of the symbol macro from the lexical environment and
avoids all the problems relating to special binding in COMPILER-LET.
(I sent out a more detailed message on the technique shortly after the
meeting.)
What I want to know, is anybody now still in favor of retaining
COMPILER-LET? Kent, since you're the one who has argued for
COMPILER-LET most strongly in the past, do you think the
SYMBOL-MACROLET technique would be sufficient to solve the kind of
problems you now use COMPILER-LET for? Or do you still want to keep
COMPILER-LET around anyway?
-Sandra
-------
∂16-Feb-89 1058 CL-Compiler-mailer issue COMPILER-LET-CONFUSION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Feb 89 10:58:42 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 540499; Thu 16-Feb-89 13:55:05 EST
Date: Thu, 16 Feb 89 13:54 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-LET-CONFUSION
To: sandra%defun@CS.Utah.EDU
cc: CL-Compiler@SAIL.Stanford.EDU, kmp@STONY-BROOK.SCRC.Symbolics.COM,
iim@ECLA.USC.EDU
In-Reply-To: <8901220315.AA18001@defun.utah.edu>,
<8902161808.AA05566@defun.utah.edu>
<12469353505.28.IIM@ECLA.USC.EDU>
Message-ID: <890216135444.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Sat, 21 Jan 89 20:15:11 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
At the Hawaii meeting, Kim Barrett showed me a clever example of how
you can already get this effect using SYMBOL-MACROLET.
Where one would now write something like:
(compiler-let ((*foo* (new-value)))
... (some-macro) ...)
(defmacro some-macro ()
... *foo* ...)
one could instead use SYMBOL-MACROLET:
(symbol-macrolet ((*foo* (new-value)))
... (some-macro) ...)
(defmacro some-macro (&environment env)
... (symbol-macro-value '*foo* env) ...)
(defun symbol-macro-value (symbol env &optional default)
(multiple-value-bind (expansion macro-p) (macroexpand-1 symbol env)
(if macro-p expansion default)))
Date: Thu, 16 Feb 89 11:08:26 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
... What I want to know, is anybody now still in favor of retaining
COMPILER-LET? Kent, since you're the one who has argued for COMPILER-LET
most strongly in the past, do you think the SYMBOL-MACROLET technique
would be sufficient to solve the kind of problems you now use COMPILER-LET
for? Or do you still want to keep COMPILER-LET around anyway? ...
I looked at this when you first sent it out and it looked buggy to me
and so I put it aside until I had more time. I'm sorry for taking so long
to get around to it, but now that I've looked at it in more detail, I still
see the same bug.
Maybe I'm just confused about what you're suggesting. If so, maybe the
following info will help you to be more clear so I can see what you are
getting at. I see the following screw case, which your example doesn't
really say how to deal with because it's not full elaborated:
The whole problem with COMPILER-LET in the past, that originally brought
all this up, is:
(DEFVAR *FOO* 0)
(DEFUN FOO ()
(COMPILER-LET ((*FOO* 1))
*FOO*))
My claim is that this should reliably return 0, not 1. Certainly it would
if a semantic-prepass were required because the dynamic environment of
execution would not overlap with the dynamic environment of compilation.
I grant that CLtL now says that it may return either 0 or 1.
I presume, of course, that the COMPILER-LET was really introduced by a macro
to communicate with another macro that might or might not be there, and that
in this case it is not there, and that therefore the programmer's intent was
effectively to just execute
(DEFVAR 0)
(DEFUN FOO () *FOO*)
Now in your proposed solution, you say I should write instead:
(DEFVAR *FOO* 0)
(DEFUN FOO ()
(SYMBOL-MACROLET ((*FOO* (NEW-VALUE)))
*FOO*))
I don't see how this has solved any problems. In fact, it has introduced some.
Because now it reliably returns the value that I don't want.
Am I missing something?
∂16-Feb-89 1112 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Feb 89 11:12:02 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA08589; Thu, 16 Feb 89 12:10:06 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05619; Thu, 16 Feb 89 12:10:02 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902161910.AA05619@defun.utah.edu>
Date: Thu, 16 Feb 89 12:10:01 MST
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.Stanford.EDU,
Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Thu, 16 Feb 89 13:09 EST
Well, I was hoping the person who has made the most noise in the past
about the nesting behavior would speak up again in his own defense. :-)
Here's my own position on the issue, which you can quote me on if you
want.
In the processing situations that are controlled by EVAL and LOAD, the
absence of the situation from an outer EVAL-WHEN means that that
processing simply will not be performed on its body, regardless of
whether the body contains nested EVAL-WHENs which do specify the
appropriate situation. However, if an outer EVAL-WHEN does not
specify COMPILE, this does not necessarily suppress all compile-time
evaluation of its body, since EVAL-WHENs nested inside the body which
do specify the COMPILE situation can also cause compile-time
evaluation. I think this asymmetry in the handling of the COMPILE
situation is confusing and unaesthetic.
I am also concerned about the complexity of the specification for the
behavior of EVAL-WHEN. I believe it is possible to come up with a
much simpler specification that also "fixes" the nesting problem.
As I said in my original reply, I'm willing to work on such an
alternate proposal if others are interested in seeing it, but if
everybody else is already perfectly happy with your new proposal I
won't try to obstruct it.
-Sandra
-------
∂16-Feb-89 1128 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 16 Feb 89 11:28:09 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA20287; Thu, 16 Feb 89 11:29:08 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA01437; Thu, 16 Feb 89 11:25:38 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA16172; Thu, 16 Feb 89 11:28:43 PST
Date: Thu, 16 Feb 89 11:28:43 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8902161928.AA16172@clam.sun.com>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM, sandra%defun@cs.utah.edu
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Cc: CL-Compiler@SAIL.Stanford.EDU, Moon@STONY-BROOK.SCRC.Symbolics.COM
My two bits worth:
All of Kent's examples of usage of EVAL-WHEN look like good
ones to me also. So do Sandra's examples.
Perhaps we need two proposals -- one compatible (or almost
compatible?) with CLtL, and one not.
The question of whether you would want to postpone
the action of a defmacro to loadtime is a red herring.
A more useful question is whether a programmer might reasonably want
to postpone *some* action normally done at compiletime so
it is done only at loadtime (using EVAL-WHEN). Even better
is the question of whether programmers should be able to
control exactly when forms get executed, even when they
themselves expand into EVAL-WHENs.
My answer to this last question is YES, so I favor full ability
to shadow inner EVAL-WHENs over greater compatibility with CLtL.
(EVAL-WHEN (:EXECUTE) . . . ) I don't know.
∂16-Feb-89 1144 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Feb 89 11:44:36 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 540570; Thu 16-Feb-89 14:42:01 EST
Date: Thu, 16 Feb 89 14:41 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: cperdue@Sun.COM
cc: CL-Compiler@SAIL.Stanford.EDU, Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8902161928.AA16172@clam.sun.com>
Message-ID: <890216144136.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Thu, 16 Feb 89 11:28:43 PST
From: cperdue@Sun.COM (Cris Perdue)
... The question of whether you would want to postpone
the action of a defmacro to loadtime is a red herring.
A more useful question is whether a programmer might reasonably want
to postpone *some* action normally done at compiletime so
it is done only at loadtime (using EVAL-WHEN). ...
I agree it's a reasonable goal, but why are you predisposed to believe that
using EVAL-WHEN has to be the way to get it done? We've offered a way to
get that effect: make the form in question non-top-level, and then execute
it when you want to.
Really it's a tried-and-true solution -- the same solution we give people
who program using DEFUN-free `batch' scripts of SETQ's and function calls
when they eventually decide they want more control than just load-time
imperative execution of everything they write. ``Write a DEFUN,'' we tell
them. ``Put that in the file and then call the defined function whenever
you want the effect to happen. Either at LOAD time or later.'' Why not use
the same technique to solve this analogous problem?
∂16-Feb-89 1238 CL-Compiler-mailer Re: issue COMPILER-LET-CONFUSION
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Feb 89 12:37:54 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA10653; Thu, 16 Feb 89 13:36:04 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05682; Thu, 16 Feb 89 13:35:16 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902162035.AA05682@defun.utah.edu>
Date: Thu, 16 Feb 89 13:35:15 MST
Subject: Re: issue COMPILER-LET-CONFUSION
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.Stanford.EDU, iim@ECLA.USC.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Thu, 16 Feb 89 13:54 EST
> I presume, of course, that the COMPILER-LET was really introduced by a macro
> to communicate with another macro that might or might not be there, and that
> in this case it is not there [...]
>
> Now in your proposed solution, you say I should write instead:
>
> (DEFVAR *FOO* 0)
> (DEFUN FOO ()
> (SYMBOL-MACROLET ((*FOO* (NEW-VALUE)))
> *FOO*))
>
> I don't see how this has solved any problems. In fact, it has introduced some.
> Because now it reliably returns the value that I don't want.
I don't think this problem is unique to using SYMBOL-MACROLET in this
way.
If the SYMBOL-MACROLET (which replaces the COMPILER-LET) was
introduced by a macro and the symbol is not supposed to be visible to
ordinary user code, then it should be a gensym instead of some random
symbol. That would avoid any accidental name collisions with a symbol
that is being used as a variable (special or not) in the code in which
the original macro call appears.
I've had to use gensyms as the names of ordinary MACROLET macros in a
couple of situations already, where I had a macro that expanded into
some local macro definitions that weren't supposed to be visible to or
shadowed by random user code in the body, but that were supposed to be
visible in the expansions of some other macros. I don't see how having
to do this for the names of symbol macros is any different.
-Sandra
-------
∂16-Feb-89 1330 CL-Compiler-mailer Re: issue COMPILER-LET-CONFUSION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Feb 89 13:30:29 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 540698; Thu 16-Feb-89 16:26:37 EST
Date: Thu, 16 Feb 89 16:26 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue COMPILER-LET-CONFUSION
To: sandra%defun@cs.utah.edu
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU,
iim@ECLA.USC.EDU
In-Reply-To: <8902162035.AA05682@defun.utah.edu>
Message-ID: <890216162621.3.KMP@BOBOLINK.SCRC.Symbolics.COM>
The whole point to giving a variable a name is so you can type it.
If (COMPILER-LET ((*FOO* (NEW-VALUE))) ...)
turns into (SYMBOL-MACROLET ((#:G0001 (NEW-VALUE))) ...)
then how can I later reference the thing. How will the lookup
routine be able to take *FOO* as an argument and figure out what
the gensym was called? If there's a place to store that relation,
why not just store the relation between *FOO* and the value itself
rather than indirecting through an irrelevant macroexpand?
Also, somewhat unrelated but I just thought of it, the body of
SYMBOL-MACROLET is not (necessarily) executed at binding time,
while *COMPILER-LET*'s body is. I'm not sure how that will affect
things. I can't convince myself that delaying the evaluation of
that form will have the right effect. [Even if it did, you'd need
to do (EVAL (MACROEXPAND ...)), not just (MACROEXPAND ...) in
the lookup routine unless you made the simplification I alluded
to in the previous paragraph.]
If you want to continue to pursue this, I guess I need to see
the fully elaborated technique described again, taking into
account the need for clarifaction on the points I've raised,
so that I can reevaluate it anew without feeling like there are
kinds of loose ends that might or might not be answered already
or that i might or might not have to magically factor in...
∂16-Feb-89 1437 CL-Compiler-mailer Re: issue COMPILER-LET-CONFUSION
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Feb 89 14:37:34 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA14505; Thu, 16 Feb 89 15:35:45 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05745; Thu, 16 Feb 89 15:35:39 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902162235.AA05745@defun.utah.edu>
Date: Thu, 16 Feb 89 15:35:37 MST
Subject: Re: issue COMPILER-LET-CONFUSION
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.Stanford.EDU, iim@ECLA.USC.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Thu, 16 Feb 89 16:26 EST
Looking at what happens to the LOCAL-TYPE-DECLARE/TYPED-VAR example
we've been using may help clarify things. Since you initially
suggested this example as being a prototypical use of COMPILER-LET, I
would think that most of what I've done with it would apply equally
well to other uses.
Your implementation using COMPILER-LET was:
(defvar *local-type-declarations* '())
(defmacro local-type-declare (declarations &body forms)
`(compiler-let ((*local-type-declarations*
(append ',declarations *local-type-declarations*)))
,@forms))
(defmacro typed-var (var)
(let ((type (assoc var *local-type-declarations*)))
(if type `(the ,(cadr type) ,var) var)))
This could be implemented using SYMBOL-MACROLET like:
(let ((temp (gensym)))
(defmacro local-type-declare (declarations &body forms &environment env)
`(symbol-macrolet ((,temp ,(append declarations
(symbol-macro-value temp env))))
,@forms))
(defmacro typed-var (var &environment env)
(let ((type (assoc var (symbol-macro-value temp env))))
(if type `(the ,(cadr type) ,var) var)))
)
(defun symbol-macro-value (symbol env &optional default)
(multiple-value-bind (expansion macro-p) (macroexpand-1 symbol env)
(if macro-p expansion default)))
Now to answer your specific questions.
> How will the lookup routine be able to take [the name of the symbol]
> as an argument and figure out what the gensym was called?
Here, I've made it a lexical variable. Both macros have a handle on
it and nobody else can possibly be using that symbol. I could have
made it a special or a DEFCONSTANT instead.
> If there's a place to store that relation,
> why not just store the relation between [the symbol] and the value itself
> rather than indirecting through an irrelevant macroexpand?
Because the macroexpand guarantees that you'll get the right value for
the -lexical- scope in which the macro -call- appears. (Not the
dynamic scope of the call, or the lexical scope of its definition, or
any of the other possible permutations.) The macroexpand is
definitely not "irrelevant"; it's at the very core of the technique.
> Also, somewhat unrelated but I just thought of it, the body of
> SYMBOL-MACROLET is not (necessarily) executed at binding time,
> while*COMPILER-LET*'s body is. I'm not sure how that will affect
> things. I can't convince myself that delaying the evaluation of
> that form will have the right effect. [Even if it did, you'd need
> to do (EVAL (MACROEXPAND ...)), not just (MACROEXPAND ...) in
> the lookup routine unless you made the simplification I alluded
> to in the previous paragraph.]
It took me a minute to figure out what you might be referring to here;
do you mean that the -value- (not body) of the symbol macro is a
literal constant? I took care of that by having the macro that
produces the SYMBOL-MACROLET do the evaluation. Look closely at the
backquoted expression in the two versions of LOCAL-TYPE-DECLARE. Note
that the COMPILER-LET version could also have done the APPEND at
macroexpand time instead of including it in the macroexpansion.
Are you still confused?
-Sandra
-------
∂17-Feb-89 1849 CL-Compiler-mailer re: COMPILER-LET-CONFUSION
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 17 Feb 89 18:49:14 PST
Date: Thu 16 Feb 89 16:50:53-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: re: COMPILER-LET-CONFUSION
To: sandra%defun@CS.UTAH.EDU
cc: kmp@SCRC-STONY-BROOK.ARPA, cl-compiler@SAIL.STANFORD.EDU,
iim%ECLA@ECLC.USC.EDU
Message-ID: <12471247919.24.IIM@ECLA.USC.EDU>
There's a minor bug and a non-CLtL-ism in your version of the
local-type-declaration example, but you've got the technique right.
First, CLtL says macro expanders are defined in the null lexical environment,
so you don't have the option of using the lexical TEMP, you have to use a
global. Second, there's a missing quote (see below).
(defmacro local-type-declare (declarations &body forms &environment env)
`(symbol-macrolet ((,temp ',(append declarations
;;*** Missing quote ↑
(symbol-macro-value temp env))))
,@forms))
kab
-------
∂18-Feb-89 0759 CL-Compiler-mailer re: COMPILER-LET-CONFUSION
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 18 Feb 89 07:59:40 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA05526; Sat, 18 Feb 89 08:57:37 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA06803; Sat, 18 Feb 89 08:57:33 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902181557.AA06803@defun.utah.edu>
Date: Sat, 18 Feb 89 08:57:32 MST
Subject: re: COMPILER-LET-CONFUSION
To: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Cc: sandra%defun@cs.utah.edu, kmp@SCRC-STONY-BROOK.ARPA,
cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>, Thu 16 Feb 89 16:50:53-PST
As to putting the DEFMACROs inside a LET, I was assuming
DEFINING-MACROS-NON-TOP-LEVEL:ALLOW passes. I probably should have
been explicit about that, sorry.
As to the missing quote -- are you sure? Wouldn't you then need to
have SYMBOL-MACRO-VALUE do an EVAL to remove the quote? From reading
the CLOS chapter 2 document I got the impression that the value of
a symbol macro is a literal constant and you should only quote it if
you want the quote to show up in the macroexpansion.
-Sandra
-------
∂21-Feb-89 1458 CL-Compiler-mailer Issue COMPILER-LET-CONFUSION
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 21 Feb 89 14:58:33 PST
Date: Sat 18 Feb 89 19:20:14-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: Issue COMPILER-LET-CONFUSION
To: sandra%defun@CS.UTAH.EDU
cc: cl-compiler@SAIL.STANFORD.EDU, iim%ECLA@ECLC.USC.EDU
Message-ID: <12471799396.5.IIM@ECLA.USC.EDU>
You're right about the QUOTE. I just looked it up and 88-002R says
"Each reference to SYMBOL as a variable within the lexical scope of
SYMBOL-MACROLET is replaced by EXPANSION (not the result of evaluating
EXPANSION)."
So I goofed and thought it was a form which returned an expansion. After
thinking about it a bit, I've convinced myself that making it an expression
that gets evaluated is probably the wrong thing to do anyway, so I'm not even
going to complain about the spec.
kab
-------
∂21-Feb-89 1458 CL-Compiler-mailer Issue WITH-COMPILATION-UNIT
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 21 Feb 89 14:58:19 PST
Date: Sat 18 Feb 89 19:17:10-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: Issue WITH-COMPILATION-UNIT
To: kmp@SCRC-STONY-BROOK.ARPA
cc: cl-compiler@SAIL.STANFORD.EDU, iim%ECLA@ECLC.USC.EDU
Message-ID: <12471798838.5.IIM@ECLA.USC.EDU>
Kent,
Some time back you made a proposal called WITH-COMPILATION-UNIT, which
currently seems to be dying for lack of any interest. Well, it turns out that
some things I've been thinking about regarding remote environments might best
be handled via such a construct.
What I'd like is to make the syntax of the macro be something like
WITH-COMPILATION-UNIT var &body body
and add something like the following to it description
The body is processed with var bound to a compile-time environment. The
extent of the environment is the dynamic extent of the form. This extent also
applies to any environments made from it (directly or indirectly) by
AUGMENT-ENVIRONMENT (see Issue SEMANTIC-ENVIRONMENT-ACCESS).
There is a need for some way to specify cleanup forms to be processed on exit.
This possibility was mentioned in your original proposal.
COMPILE-FILE needs a :environment argument. Without it, there isn't a good way
to inform COMPILE-FILE that there is an outer environment that it should be
refering to (a special doesn't work for the same reason it doesn't work for
things like FIND-CLASS). Conceivably, COMPILE should also be extended to take
an environment argument, but I'm not sure of the need for it, nor convinced
that it is really desirable. I'm fairly certain it is not needed for what I'm
trying to accomplish. Not extending COMPILE this way would prohibit it from
taking part in a compilation unit.
kab
-------
∂21-Feb-89 1458 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS, v2
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 21 Feb 89 14:58:26 PST
Date: Sat 18 Feb 89 19:18:47-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: Issue SYNTACTIC-ENVIRONMENT-ACCESS, v2
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim%ECLA@ECLC.USC.EDU
Message-ID: <12471799132.5.IIM@ECLA.USC.EDU>
In the discussion for SEMANTIC-ENVIRONMENT-ACCESS version 2 (SEA-2) I mentioned
that there are some accessor/update pairs associated with defining forms which
are missing from Common Lisp. Below is a table of all the Common Lisp defining
macros (assuming I haven't missed any), along with their associated functions
(where specified).
Note that this isn't just a mindless exercise in filling holes. The missing
functions are needed if you want to write a portable 'file compiler' that wants
to treat these forms as special-forms that it knows how to deal with, since to
do so in any reasonable fashion requires hooking into the implementations
mechanisms for recording compile-time information.
Defining form Accessor Create/Update
-------------------------------------------------------------------------------
DEFCLASS FIND-CLASS ENSURE-CLASS
DEFCONSTANT CONSTANTP **
DEFGENERIC FDEFINITION * ENSURE-GENERIC-FUNCTION
DEFINE-METHOD-COMBINATION FIND-METHOD-COMBINATION *
DEFINE-MODIFY-MACRO MACRO-FUNCTION (SETF MACRO-FUNCTION)
DEFINE-SETF-METHOD GET-SETF-METHOD
DEFMACRO MACRO-FUNCTION (SETF MACRO-FUNCTION)
DEFMETHOD FDEFINITION * ENSURE-GENERIC-FUNCTION
DEFPARAMETER *** ***
DEFSETF GET-SETF-METHOD
DEFSTRUCT FIND-CLASS ENSURE-CLASS
DEFTYPE
DEFUN FDEFINITION * (SETF FDEFINITION) *
DEFVAR *** ***
* Assuming proposal FUNCTION-NAME:LARGE.
** Does not currently take an environment argument.
*** Functions for SPECIAL proclamations would supply these (see below).
TYPEP and SUBTYPEP also need environment arguments, for reasons which were
discussed on the mailing list in January.
DEFPACKAGE has FIND-PACKAGE and MAKE-PACKAGE as its accessor and updator, but
no local vs remote distinction is currently specified.
Many compilers treat PROCLAIM specially when it appears at top level (not doing
so seriously reduces the utility of proclamations). I think such treatment
ought to be made official, though possibly through the use of a macro, as is
being proposed for IN-PACKAGE => SELECT-PACKAGE. If we do so, the various
declarations that are allowed by proclaim might also need functions.
Note that none of these has an accessor defined in CLtL, and the only
create/update function defined in CLtL is PROCLAIM, which does not take an
environment argument. Note that SEA-2 does not deal with all of these.
Declaration SEA-2
-----------------------------
SPECIAL yes
TYPE yes
FTYPE yes
FUNCTION yes (by transformation to FTYPE)
INLINE no
NOTINLINE no
IGNORE no
OPTIMIZE no
DECLARATION no
Perhaps an AUGMENT-GLOBAL-ENVIRONMENT function needs to be added to SEA, to
record proclamations? I think that such a function, combined with the accessor
functions in SEA would deal with DEFVAR and DEFPARAMETER, assuming that it is
never interesting to know that a variable is proclaimed special, rather than
either proclaimed or declared special (and similarly for type, ftype, and
lexical (if needed due to PROCLAIM-LEXICAL)).
kab
-------
∂21-Feb-89 1502 CL-Compiler-mailer Issue CONSTANT-CIRCULAR-COMPILATION, v6
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 21 Feb 89 15:02:43 PST
Date: Sun 19 Feb 89 15:51:42-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: Issue CONSTANT-CIRCULAR-COMPILATION, v6
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim%ECLA@ECLC.USC.EDU
Message-ID: <12472023576.5.IIM@ECLA.USC.EDU>
For Current Practice and Discussion: IIM also implements YES.
-------
∂21-Feb-89 1502 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL, v5
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 21 Feb 89 15:02:34 PST
Date: Sun 19 Feb 89 15:50:40-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL, v5
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim%ECLA@ECLC.USC.EDU
Message-ID: <12472023390.5.IIM@ECLA.USC.EDU>
I think a lot of my disagreement with this proposal is founded on differing
ideas about what the various situations mean.
Under version 4 model:
EVAL the interpreter (EVAL) should process the body.
LOAD the compiler should process the body.
COMPILE the compiler should make the interpreter process the body at
compile-time.
Under version 5 model:
EVAL says I want code run in embedded code.
LOAD says I want code run at top-level when loading.
COMPILE says I want code run at top-level when compiling.
The COMPILE situations are the same. The differences are in the LOAD and EVAL
situations, and possibly in how they interact with the COMPILE situation.
For nesting behavior, an implication of version 4 is that an EVAL-WHEN always
limits the set of situations which will apply in EVAL-WHEN forms which are
nested within it. This is not true of version 5.
Here are a couple of concrete examples where these models differ.
1. DEFMACRO
If we write DEFMACRO as follows (proponents of both version 4 and version 5
believe this is a reasonable way to write it):
(defmacro DEFMACRO (name bvl &body body)
`(progn
(eval-when (compile)
(compiler::note-defmacro ',name ',bvl ',body))
(setf (macro-function ',name) #'(lambda ...))))
If we wrap a defmacro in an (eval-when (compile load eval) ...) then we get the
following behaviors when compiled (both versions exhibit the same behavior when
interpreted).
effective expansion
(eval-when (compile load eval)
(eval-when (compile)
(compiler::note-defmacro ',name ',bvl ',body))
(setf (macro-function ',name) #'(lambda ...)))
version 4
Step 1. The outer EVAL-WHEN specifies the COMPILE situation and we are at
top-level, so call EVAL on each of the body forms. The first body form is
an EVAL-WHEN without the EVAL situation, so it evaluates to NIL. The
second body form is evaluated.
Step 2. The outer EVAL-WHEN specifies the LOAD situation, so process the
body as a non-top-level PROGN. The first body form is an EVAL-WHEN
specifying only the COMPILE situation. Since we are not at top-level, it
is treated as NIL. The second form is processed normally.
version 5
The outer EVAL-WHEN specifies the COMPILE situation, so switch to
compile-time-too mode while processing the body forms. The first body form
is an EVAL-WHEN with only the COMPILE situation specified, so evaluate the
body as an implicit PROGN. The second form is not an EVAL-WHEN. Since we
are in compile-time-too mode, evaluate it. Now do normal processing on it.
The difference is that version 4 ignores the inner (EVAL-WHEN (COMPILE) ...),
while version 5 evaluates it. It seems rather pointless to record the macro in
the compiler's remote environment when you are about to define it in the local
environment. Two counter-arguments come to mind. First, you may be redefining
a macro that appeared earlier in the file without having such an EVAL-WHEN
wrapped around it. But most of the comments I've heard on these mailing lists
about similar things is that they are an error. Second, this may be necessary
(and possibly the only way) to define a recursive macro (that is, a macro whose
expander function (not its expansion) calls that same macro). Do we really
need to support such critters?
2. The EVAL situation
Some implications of version 5
(EVAL-WHEN (EVAL) . BODY) == NIL when at top-level
(EVAL-WHEN (EVAL) . BODY) == (PROGN . BODY) when at non-top-level
Thus, under version 5, there is no way (at non-top-level) to distinguish
between the case where the compiler is processing the code and the case where
the interpreter is processing the code, and the behavior of the EVAL situation
is radically different, depending on whether you are at top-level or not, which
makes it harder to reason about what the EVAL situation means, and whether or
when you should use it.
Under version 4, the compiler and interpreter cases are distinguishable. An
example where this distinction was useful is a definition of
PCL::LOAD-TIME-EVAL I wrote some time ago for our system:
(defmacro load-time-eval (form)
(let ((gensym (gensym)))
`(block ,gensym
(eval-when (eval)
(return-from ,gensym (eval ',form)))
(eval-when (load)
<< stuff to hook into compiler's load-time evaluation stuff >>))))
I think that we are approaching agreement on this stuff. I feel comfortable
with most of the points made in the Backgroud/Analysis and
Clarifications/Consequences sections of version 5. I don't have a strong
objection to introducing a compile-time-too state into version 4 to keep the
evaluation due to a COMPILE situation in lock-step with the normal processing
of the forms. My main reason for wanting to avoid it is that the resulting
description seems (to me, at least) much simpler and easier to understand.
kab
-------
∂21-Feb-89 1501 Common-Lisp-Object-System-mailer Issue MACRO-ENVIRONMENT-EXTENT
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 21 Feb 89 15:01:07 PST
Date: Sun 19 Feb 89 15:54:36-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: Issue MACRO-ENVIRONMENT-EXTENT
To: sandra%defun@CS.UTAH.EDU
cc: Moon@SCRC-STONY-BROOK.ARPA, iim%ECLA@ECLC.USC.EDU,
cl-compiler@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <12472024104.5.IIM@ECLA.USC.EDU>
> From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Sun, 12 Feb 89 19:20:29 MST
>
> Having seen the new proposal for EVAL-WHEN, I still don't have any idea why
> the extent of macro environment objects depends on it. Can you explain the
> connection?
>
> Also, I don't think anybody is arguing for requiring environments to have
> indefinite extent on the grounds that CLOS requires it. (The argument is
> that it's generally useful and for general symmetry with every other kind of
> Lisp data object having indefinite extent.) Just the opposite -- David Gray's
> question was whether that requirement would complicate the implementation of
> CLOS.
The extent of macro environment objects is related to EVAL-WHEN because macro
expanders may wish to return forms which contain environments as quoted
constants. For example:
(defclass position (graphics-object)
((x :accessor position-x :initform 0 :type integer)
(y :accessor position-y :initform 0 :type integer)
(pen-color :allocation :class))
(:default-initargs :screen *position-screen*))
=>
`(progn
(eval-when (compile)
(ensure-class 'position
:metaclass (find-class 'standard-class)
:superclasses (list (find-class 'graphics-object t ',<env>)) ; <= ***
:direct-slots
(list (make-instance 'standard-direct-slot
:name 'x
:initform '0
:readers '(position-x)
:writers '((setf position-x))
:type 'integer)
...
)
:default-initargs
(list (list ':screen '*position-screen* nil))
:environment ',<env>) ; <= ***
)
(ensure-class 'position
:metaclass (find-class 'standard-class)
:superclasses (list (find-class 'graphics-object))
:direct-slots
(list (make-instance 'standard-direct-slot
:name 'x
:initform '0
:initfunction #'(lambda () 0)
:readers '(position-x)
:writers '((setf position-x))
:type 'integer)
...
)
:default-initargs
(list (list ':screen '*position-screen*
#'(lambda () *position-screen*))))
)
Not saying anything about their extent may make such an expansion invalid,
because the expansion might be returned from the dynamic extent of the
environment it points to. Requiring environments to have indefinite extent has
problems for CLOS because at compile-time it wants to create remote metaobjects
and link them into the right places, but then flush those links when the
compilation is over. This is what I am trying to address with my recent
comments about WITH-COMPILATION-UNIT.
kab
-------
∂21-Feb-89 1501 Common-Lisp-Object-System-mailer Issue CONSTANT-COMPILABLE-TYPES
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 21 Feb 89 15:01:51 PST
Date: Sun 19 Feb 89 15:48:59-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: Issue CONSTANT-COMPILABLE-TYPES
To: JonL@LUCID.COM, sandra%defun@CS.UTAH.EDU
cc: Moon@SCRC-STONY-BROOK.ARPA, iim%ECLA@ECLC.USC.EDU,
cl-cleanup@SAIL.STANFORD.EDU, cl-compiler@SAIL.STANFORD.EDU,
common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <12472023082.5.IIM@ECLA.USC.EDU>
The message that prompted this response was sent only to cl-compiler. Since my
response touches on issues of more general interest, I've included cl-cleanup
and common-lisp-object-system as well. Appologies in advance -- this turned
out to be a bit of a tirade.
> Date: Tue, 31 Jan 89 05:05:58 PST
> From: Jon L White <jonl@lucid.com>
>
> > I disagree with the idea of changing the handling for structures.
> > Introducing the LOAD-OBJECTS protocol for standard-class instances is fine,
> > but structures have been part of the language for a while already and I
> > don't see any need to change their handling in an incompatible way. If
> > people find that the default handling of structures is not sufficient for
> > their needs, that's probably a sign that they really need to use the more
> > complex protocol for standard-class objects instead.
>
> I very much agree with what you say here. Unfortunately, not enough
> people objected at the right time -- when the vote on 88-002R was being
> taken -- and this "trojan horse" sneaked in to destroy the defstruct
> house. [in fact, I wonder how many people actualy read 88-002R before
> voting on it?] It's possible that changing the default defstructs to be
> CLOS instances will make it smoother for PCL transition; but I don't see
> how the incompatible changes to the :PRINT-FUNCTION, :COPIER, and
> EQUALP treatment on defstructs helps anyone.
>
> ...
>
> Unfortunately, the EQUAL-STRUCTURE amendment that passed at the Hawaii
> meeting retracted this very useful action of EQUALP on defstructs, and
> rendered it useless again. Hopefully, the final version of the LOAD-
> OBJECTS proposal will specify a more useful default behaviour (e.g.,
> "just like the old CLtL behaviour"?), but note it this will have to
> amend the already-passed EQUAL-STRUCTURE proposal.
>
> -- JonL --
I wish to strongly disagree with almost everything said above. There is a
fundamental assumption being made, namely that structures are second-class
citizens in the CLOS world. This is most clearly expressed by the statement
"If people find that the default handling of structures is not sufficient for
their needs, that's probably a sign that they really need to use the more
complex protocol for standard-class objects instead."
This is terrible! Awful! Totally wrong!
Structures have certain restrictions (single inheritance, don't support
CHANGE-CLASS, ...) in exchange for potentially very efficient access. When
deciding whether to implement a data structure using STRUCTURE-CLASS vs
STANDARD-CLASS, the question a programmer should be asking is "does this class
need multiple inheritance ...", not "am I ever going to need to dump one of
these things, or compare two of them using EQUALP, or ...".
Moon keeps pointing out that only the programmers who define/use a class can
know how to properly copy, dump, test for equality (whatever equality means),
&etc. Unfortunately, under strong pressure from some people he occasionally
sounds like he is willing to cave in on this point in the case of structures.
Well I won't. Removing structure objects from these kinds of protocols and
instead giving them trivial component-wise functionality is utter nonsense. By
all means we should give the programmer mechanisms to help him specify that
kind of behavior if that is what he wants. But it must be a concious decision,
not a default behavior! (As an aside, if it were up to me, the default copier
option for defstruct would be Nil.)
With regard to the EQUAL-STRUCTURE amendment that passed at the Hawaii meeting,
I insisted on EQ for structures because I firmly believe that is the right
default. I would still like to see a proposal to make EQUALP a generic
function; unfortunately, the group who said they would make such a proposal
have not done so. I was thinking about making such a proposal myself, but I've
been having trouble with the specification of the hash function, due to some
ideas I've been working on with regard to hash-table implementations.
kab
-------
∂22-Feb-89 1819 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ECLC.USC.EDU by SAIL.Stanford.EDU with TCP; 22 Feb 89 18:18:15 PST
Date: Wed 22 Feb 89 16:27:51-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Subject: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: cl-compiler@SAIL.STANFORD.EDU
cc: eb@LUCID.COM, iim%ECLA@ECLC.USC.EDU
Message-ID: <12472816591.21.IIM@ECLA.USC.EDU>
Issue: SYNTACTIC-ENVIRONMENT-ACCESS
References: CLtL Chapter 8: Macros,
Issue MACRO-FUNCTION-ENVIRONMENT,
Issue GET-SETF-METHOD-ENVIRONMENT,
Issue COMPILE-FILE-ENVIRONMENT
Related Issues: Issue FUNCTION-NAME,
Issue PROCLAIM-LEXICAL
Category: ADDITION
Edit history: Version 1, 2-Oct-88, Eric Benson
Version 2, 17-Feb-89, Kim A. Barrett
Status: For internal discussion
Problem description:
When macro forms are expanded, the expansion function is called with two
arguments: the form to be expanded, and the environment in which the form was
found. The environment argument is of limited utility. The only use
sanctioned currently is as an argument to MACROEXPAND or MACROEXPAND-1 or
passed directly as an argument to another macro expansion function. Recent
cleanup issues propose to allow it as an argument to MACRO-FUNCTION and to
GET-SETF-METHOD.
Implementing the FIND-CLASS and ENSURE-GENERIC-FUNCTION functions of CLOS
requires the ability to distinguish between environments used for compiling to
a file from those used for processing in-core, such as by EVAL or COMPILE.
Resolution of the LOAD-TIME-EVAL issue may also require this information.
This problem has been addressed by the recent cleanup issue
COMPILE-FILE-ENVIRONMENT. Also, it has proven impossible to write a portable
code walker in Common Lisp, due to insufficient access to the information
contained in environments and the inability to augment environments with local
function definitions.
Proposal (SYNACTIC-ENVIRONMENT-ACCESS:ADD-FUNCTIONAL-INTERFACE):
The following functions provide information about syntactic environment
objects. In all of the functions the argument named ENV is a environment, of
the sort received by the &ENVIRONMENT argument to a macro, or as the
environment argument for EVALHOOK. In all cases it is an error to supply an
argument which is not a syntactic environment.
ENVIRONMENT-TARGET env [Function]
This function returns one of the three symbols :EVAL, :COMPILE or
:COMPILE-FILE, depending on whether the environment is from the interpreter,
the in-core compiler, or the file compiler. If MACROEXPAND or MACROEXPAND-1
is called directly without supplying the environment argument, the
environment passed to any expander functions will have target :EVAL.
ENVIRONMENT-VARIABLE-KIND variable env [Function]
VARIABLE is a symbol. This function returns one of the folloing symbols,
depending on the type of definition or binding which is apparent in ENV.
NIL There is no apparent definition or binding for variable.
:SPECIAL VARIABLE refers to a special variable, either declared or
proclaimed.
:LEXICAL VARIABLE refers to a lexical variable.
:SYMBOL-MACRO VARIABLE refers to a SYMBOL-MACROLET binding.
:CONSTANT VARIABLE refers to a named constant, defined by DEFCONSTANT.
[Note: If issue PROCLAIM-LEXICAL passes, then the :LEXICAL result will also
refer to variables proclaimed lexical.]
Example:
(DEFMACRO KIND-OF-VARIABLE (VAR &ENVIRONMENT ENV)
`',(ENVIRONMENT-VARIABLE-KIND VAR ENV))
(DEFVAR A)
(DEFUN TEST ()
(LET (B)
(LET (C)
(DECLARE (SPECIAL C))
(SYMBOL-MACROLET ((D ANYTHING))
(LIST (KIND-OF-VARIABLE A)
(KIND-OF-VARIABLE B)
(KIND-OF-VARIABLE C)
(KIND-OF-VARIABLE D)
(KIND-OF-VARIABLE E))))))
(TEST) -> (:SPECIAL :LEXICAL :SPECIAL :SYMBOL-MACRO NIL)
ENVIRONMENT-FUNCTION-KIND function env [Function]
FUNCTION is a function name. This function returns two values, depending on
the type of function definition or function binding which is apparent for
FUNCTION in ENV.
NIL There is no apparent definition for FUNCTION.
:FUNCTION FUNCTION refers to a function.
:MACRO FUNCTION refers to a macro.
:SPECIAL-FORM FUNCTION refers to a special-form.
The second value specifies whether the definition is local or global. If
local, the second value is true, and it is false when the definition is
global.
Some function names may refer to both a global macro and a global special
form. In such a case, the macro takes precedence, and :MACRO is returned as
the first value.
[Note: The use of "function name" rather than "symbol" as the description of
the function argument is intended to be compatible with the various proposals
to extend the syntax of function specifiers. If no such change actually
occurs then this would only refer to symbols.]
Example:
(DEFMACRO KIND-OF-FUNCTION (FUNCTION-NAME &ENVIRONMENT ENV)
`',(ENVIRONMENT-FUNCTION-KIND FUNCTION-NAME ENV))
(DEFUN A ())
(DEFMACRO B ())
(DEFUN TEST ()
(FLET ((C ()))
(MACROLET ((D ()))
(MULTIPLE-VALUE-CALL #'LIST
(KIND-OF-FUNCTION A)
(KIND-OF-FUNCTION B)
(KIND-OF-FUNCTION QUOTE)
(KIND-OF-FUNCTION C)
(KIND-OF-FUNCTION D)
(KIND-OF-FUNCTION E)))))
(TEST) -> (:FUNCTION NIL
:MACRO NIL
:SPECIAL-FORM NIL
:FUNCTION T
:MACRO T
NIL NIL)
ENVIRONMENT-TYPE variable env [Function]
VARIABLE is a symbol. This function returns the type specifier
associated with the variable named by the symbol in the environment.
If no explicit association exists, either by PROCLAIM or DECLARE, then
the result is the type specifier T.
Example:
(DEFMACRO VARTYPE (VAR &ENVIRONMENT ENV)
`',(ENVIRONMENT-VARIABLE-TYPE VAR ENV))
(DEFVAR A 1)
(PROCLAIM '(FIXNUM A))
(DEFUN TEST ()
(LET ((B (AREF "X" 0))
(C 3))
(DECLARE (STRING-CHAR B))
(LIST (VARTYPE A) (VARTYPE B) (VARTYPE C))))
(TEST) -> (FIXNUM STRING-CHAR NIL)
ENVIRONMENT-FTYPE function env [Function]
FUNCTION is a function name. This function returns the functional type
specifier associated with the function in the environment, or NIL if there is
no functional type declaration or proclamation associated with the function.
Example:
(DEFMACRO FUNTYPE (FUN &ENVIRONMENT ENV)
`',(ENVIRONMENT-FTYPE FUN ENV))
(DEFUN A-FUNCTION (X)
(+ X 3))
(PROCLAIM '(FTYPE (FUNCTION (FIXNUM) FIXNUM) A-FUNCTION))
(DEFUN TEST ()
(FLET ((ANOTHER-FUNCTION (X)
(+ X 2)))
(DECLARE (FTYPE (FUNCTION (INTEGER) INTEGER) ANOTHER-FUNCTION))
(LIST (FUNTYPE A-FUNCTION) (FUNTYPE ANOTHER-FUNCTION))))
(TEST) -> ((FUNCTION (FIXNUM) FIXNUM) (FUNCTION (INTEGER) INTEGER))
AUGMENT-ENVIRONMENT env &KEY lexical
special
symbol-macro
function
macro
type
ftype [Function]
This function returns a new environment augmented with the information
provided by the keyword arguments. The arguments are supplied as follows:
:LEXICAL A list of symbols which shall be visible as lexical variables
in the new environment.
:SPECIAL A list of symbols which shall be visible as dynamic variables
in the new environment.
:SYMBOL-MACRO An alist of symbols and macroexpansion functions. The new
environment will have local symbol-macro bindings of each
symbol to the corresponding expander function, so that
MACROEXPAND will be able to expand them properly.
:FUNCTION A list of function names which shall be visible as local
function bindings in the new environment.
:MACRO An alist of function names and macroexpansion functions. The
new environment will have local macro bindings of each name to
the corresponding expander function, which will be returned by
MACRO-FUNCTION and used by MACROEXPAND.
:TYPE An alist of symbols and type specifiers. The new environment
will have the type specifier associated with the currently
visible binding of the symbol (defaulting to the global special
binding if there is no binding present). Note that in a single
call to AUGMENT-ENVIRONMENT the :TYPE argument can be thought
of as being processed after all the variable arguments have
been processed, thus allowing bindings and declarations to be
updated with a single call.
:FTYPE An alist of function names and functional type specifiers.
This is analogous to :TYPE, exept operating in the function
namespace.
While an environment argument from EVALHOOK may be used as the environment
argument for this function, the reverse is not true. It is an error to
attempt to use the result of AUGMENT-ENVIRONMENT as the environment argument
for EVALHOOK. The environment returned by AUGMENT-ENVIRONMENT may only be
used for syntactic analysis.
ENVIRONMENT-PROPERTY env name property &optional default
This function and its SETF method allow the association of arbitrary 'global'
properties with names. An environment can be thought of as having a local
property list associated with any name, and this function provides access to
that property list. The association between names and property lists uses
EQUAL to match names. The search of the property list uses EQ to match
properties. If the property is not found in the environment's local property
list, the global property list of the name is searched. If the property is
not found on the global property list, then default is returned.
Note that the global property list of a name is not necessarily the
symbol-plist of the name.
[Note: The use of EQUAL as the matching function for names is to allow for
proposed extensions to function names. If no such extension occurs, then EQ
could be used instead.]
Rationale:
This proposal provides a portable interface to environment information which
must otherwise be obtained by implementation-dependent means. The
ENSURE-GENERIC-FUNCTION and FIND-CLASS functions of CLOS require the
ENVIRONMENT-TARGET function and some mechanism similar to that supplied by the
ENVIRONMENT-PROPERTY function. A useful code walker requires the capability
of adding local function definitions to an environment.
Cost to Implementors:
Most implementations already store some of this information in some form.
Providing these functions should not be too difficult, but it is a more than
trivial amount of work.
Cost to Users:
This change is upward compatible with user code.
Current practice:
No implementation provides all of this interface currently. Portable Common
Loops defines a subset of this functionality for its code walker and
implements it on a number of diffent versions of Common Lisp. IIM uses the
functionality provided by ENVIRONMENT-TARGET and ENVIRONMENT-PROPERTY (under
other names) to implement the association between names and remote metaobjects
(macro and type definitions, CLOS remote metaobjects, &etc).
Discussion:
The first version of this proposal expressly did not deal with the objects
which are used as environments by EVALHOOK. This version is extended to
support them in the belief that such environments share a lot of functionality
with the syntactic environments needed by a compiler. While the two types of
environments may have very different implementations, there are many
operations which are reasonable to perform on either type, including all of
the accessor functions described by this proposal.
-------
-------
-------
∂23-Feb-89 0859 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from FRED.SLISP.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 23 Feb 89 08:59:41 PST
Received: from FRED.SLISP.CS.CMU.EDU by FRED.SLISP.CS.CMU.EDU; 23 Feb 89 11:56:45 EST
To: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
cc: cl-compiler@SAIL.STANFORD.EDU, eb@LUCID.COM
Subject: Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
In-reply-to: Your message of Wed, 22 Feb 89 16:27:51 -0800.
<12472816591.21.IIM@ECLA.USC.EDU>
Date: Thu, 23 Feb 89 11:56:21 EST
From: Rob.MacLachlan@WB1.CS.CMU.EDU
Could you provide some example uses of AUGMENT-ENVIRONMENT? It isn't at
all clear to me even what it is supposed to do. What does it mean to
"augment the set of visible variables?" You seem to imply that this
actually creates new variables (which could have type declarations).
I don't understand why a macro that wants to use this can't expand into
Lisp code that makes the appropriate environment manipulations.
I see the use for the environment query functions and for the environment
plist stuff, but AUGMENT-ENVIRONMENT is much more questionable. It seems
to be both of questionable utility and also to be extremely difficult to
implement.
AUGMENT-ENVIRONMENT truly horrible if any extent other than dynamic is
chosen for environments: it would be possible to retroactively introduce
variables into code that was already compiled.
Given a dynamic extent, I suppose the compiler could notice that
AUGMENT-ENVIRONMENT was called when it invoked a macro expander. It could
then decode the arguments and transduce them into the appropriate LET,
MACROLET, ... and wrap that around the expansion. What I don't see is why
the compiler should have to do this.
Rob
∂23-Feb-89 0920 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Feb 89 09:20:20 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA15931; Thu, 23 Feb 89 10:18:06 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10239; Thu, 23 Feb 89 10:17:51 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902231717.AA10239@defun.utah.edu>
Date: Thu, 23 Feb 89 10:17:49 MST
Subject: Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU, eb@LUCID.COM
In-Reply-To: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>, Wed 22 Feb 89 16:27:51-PST
> Date: Wed 22 Feb 89 16:27:51-PST
> From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
>
> Proposal (SYNACTIC-ENVIRONMENT-ACCESS:ADD-FUNCTIONAL-INTERFACE):
>
> In all of the functions the argument named ENV is a environment, of
> the sort received by the &ENVIRONMENT argument to a macro, or as the
> environment argument for EVALHOOK. In all cases it is an error to supply an
> argument which is not a syntactic environment.
One other thing that ought to be clarified here: CLtL p. 145-146 says
that the &environment argument received by a macro does not have to be
the complete lexical environment. We should be explicit that we are
changing this and requiring &environment arguments to contain all of
the information that the accessors this proposal defines can get at.
I am not so sure that extending this proposal to EVALHOOK environments
is such a good thing. For one thing, implementations that do some
kind of preprocessing or partial compilation may not have anything
like the kind of information this proposal requires available.
Another problem is that I am not convinced that this information is
really all that useful to implementations that want to use EVALHOOK.
(For instance, I've recently been working on some debugging tools
where I've wanted to do things like draw pictures of the various
lexical contours as nested boxes, showing the values of all the local
variables in those contours. This proposal wouldn't give me the kind
of information I need to do that.)
> ENVIRONMENT-TARGET env [Function]
>
> This function returns one of the three symbols :EVAL, :COMPILE or
> :COMPILE-FILE, depending on whether the environment is from the interpreter,
> the in-core compiler, or the file compiler. If MACROEXPAND or MACROEXPAND-1
> is called directly without supplying the environment argument, the
> environment passed to any expander functions will have target :EVAL.
I flamed about this at length when the last version of the proposal
came out: there are more situations than these in which code may be
processed!!! Moon suggested that we distinguish only between local
and remote environments, and rename this function ENVIRONMENT-REMOTE-P.
I think that would make a lot more sense.
> Some function names may refer to both a global macro and a global special
> form. In such a case, the macro takes precedence, and :MACRO is returned as
> the first value.
I'm not so sure that this is the right choice. Any code walker ought
to have special knowledge about things that the standard explicitly
says are special forms, even if they happen to be implemented as
macros. I think it would be more useful to return :SPECIAL-FORM in
such cases. I agree that :MACRO should be returned for things that
are documented as being macros in the standard but that also have a
special form implementation.
> ENVIRONMENT-TYPE variable env [Function]
Can we please call this function ENVIRONMENT-VARIABLE-TYPE again?
To me, ENVIRONMENT-TYPE implies that it returns information about the
kind of environment, not the type of variables in the environment.
> ENVIRONMENT-FTYPE function env [Function]
Perhaps ENVIRONMENT-FUNCTION-TYPE would be a better name?
> AUGMENT-ENVIRONMENT env &KEY lexical
> special
> symbol-macro
> function
> macro
> type
> ftype [Function]
Two problems here:
- shouldn't there be a way to create a null environment object?
- how does one specify the remoteness (or target) of the resulting
environment?
Is there any reason why the newly created environment object should
-not- have indefinite extent? One of the alternatives suggested for
issue MACRO-ENVIRONMENT-EXTENT was to allow &environment objects to
have only dynamic extent within the macro function, but to provide
some kind function to make copies that do have indefinite extent.
Would calling AUGMENT-ENVIRONMENT with no keyword arguments do that?
Also, I think it needs to be made more clear that the original
environment is not destructively modified by this function.
> ENVIRONMENT-PROPERTY env name property &optional default
>
> This function and its SETF method allow the association of arbitrary 'global'
> properties with names. An environment can be thought of as having a local
> property list associated with any name, and this function provides access to
> that property list. The association between names and property lists uses
> EQUAL to match names. The search of the property list uses EQ to match
> properties. If the property is not found in the environment's local property
> list, the global property list of the name is searched. If the property is
> not found on the global property list, then default is returned.
>
> Note that the global property list of a name is not necessarily the
> symbol-plist of the name.
This doesn't make much sense to me -- you seem to be contradicting
yourself about whether this attaches "global" or "local" properties to
names. Perhaps you mean that if the environment is a "remote"
environment, than the properties are local to that environment, but if
it's a non-remote environment, then the properties are global?
I am uncomfortable about the idea of allowing environment objects to
be destructively modified. Suppose I have an environment E1 and I
pass it to an argument to AUGMENT-ENVIRONMENT to get environment E2.
If I then modify the property list of E1, are the changes also
reflected in E2?
I think this particular item needs more rationale to support it. I
gather that this is supposed to be the internal mechanism by which
CLOS hangs information about the class structure off the environment?
Why does this need to be generalized -- what is wrong with having
FIND-CLASS be the primitive accessor for this kind of information?
-Sandra
-------
∂23-Feb-89 1023 CL-Compiler-mailer top-level, eval-when: it's not too late
Received: from FRED.SLISP.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 23 Feb 89 10:23:23 PST
Received: from FRED.SLISP.CS.CMU.EDU by FRED.SLISP.CS.CMU.EDU; 23 Feb 89 13:20:38 EST
To: cl-compiler@sail.stanford.edu
Subject: top-level, eval-when: it's not too late
Date: Thu, 23 Feb 89 13:20:34 EST
From: Rob.MacLachlan@WB1.CS.CMU.EDU
Before we go off the deep end arguing about what top-level is and how forms
should differ at top-level and elsewhere, we should seriously consider
top-level-less alternatives. I believe that the concept of top-level is
totally unnecessary for a well defined Common Lisp semantics. Furthermore,
I believe the concept of top-level is a blight on Lisp semantics:
-- Differing top-level semantics creates a totally gratuitous context
dependency. (can you say "referential transparency"?)
-- It is complex to define what top-level means (and difficult to
understand complex definitions).
-- It is difficult (perhaps impossible) to come up with a definition for
top-level that allows as much power as when there is no concept of
top-level.
What does top-level mean?
Moon:
I'd like to point out that the defining characteristic of top-level is
not that the lexical environment is null, but that the lexical environment
does not contain any variables, functions, blocks, or go tags; it
contains only declarations, macros, and the COMPILE-FILE remote/local
environment business. Also top-level is not nested inside any flow
of control (conditionals, iterations, catches [which are essentially
a kind of conditional]); that's why the compiler can treat defmacro,
for example, specially at top level, because it knows that the defmacro
will be executed exactly once at load time and in a fully known lexical
environment.
In other words, a top-level form:
-- can be proven to be evaluated at load time, and
-- has no run-time values in its environment, and thus can be evaluated at
compile time.
But why do we need this? The goal of this special treatment of top-level
forms seems to be to allow the user to believe in a naive model: there
aren't any special rules form compile-time evaluation. The compiler only
"dares" to evaluate forms at compile time when it can prove that the same
evaluations would happen in the same order at run time.
The assumption is that it is that discretion is the the better part of
valor: it is better not to evaluate a form at compile time when the naive
model might be violated. Underlying this is an assumption that:
-- It is very rare for it to be desirable to compile-time evaluate a form
and for the compiler to be unable to prove that the form will be
evaluated at run-time, and/or
-- It is "relatively harmless" to omit compile-time evaluation when
evaluation might cause confusion.
I don't agree with either of these assumptions. These assumptions only
hold for a restricted Common Lisp programming style. Given extensive
top-level use of FLET, LET, etc, many defining forms end up in an
environment that is clearly not "top-level" as defined above. Yet is is
*not* harmless for the compiler to forget to notice variable and function
declarations and definitions. Failure to notice a function definition
results in confusing spurious warnnings. Failure to notice a DEFVAR
results in code that just doesn't work.
The alternative is to not be conservative about doing compile-time
evaluation: to always evaluate an eval-when (compile) wherever it appears.
In this scheme, compile time evaluation is clearly a visibly separate
process from load-time evaluation: forms could be evaluated at compile time
that would not be evaluated at load time. There is potential for confusion
here, but in reality it isn't very confusing.
The key difference lies in the difference between what the compiler can
easily prove and what is true. Even when buried inside all kinds of gunk,
defining forms will usually be evaluated at load time even though the
compiler can't prove it. The same naive model holds as for the top-level
system. The difference is in where you fall off the edge of the naive
world. In the top-level-only evaluation model, the user finds he just
can't do what he wants to do, whereas in the always-evaluate model, he
finds that he has to insert some form that inhibits compile-time
evaluation.
Here is my proposal:
Take the original EVAL-WHEN-NON-TOP-LEVEL proposal as the meaning of
EVAL-WHEN everywhere. Continue to define compiler "noticing" to take place
as though through EVAL-WHEN. That's all you need.
A minor wart is that the compiler currently needs to notice some "magic
functions": package functions, provide & require, proclaim. At least some
of these functions have reasonable run-time uses in addition to the magic
compile-time uses, so it could cause some confusion to always evaluate
these forms at compile time wherever they appear. Fortunately,
the cleanup process seems to be eliminating most of these semantically
bletcherous functions.
Even if the magic functions aren't all eliminated, we still don't need
top-level. As long as there is some eval-when-oid mechanism that inhibits
enclosed eval-when (compile)s, any uses of magic functions that don't want
to be magic can be wrapped in this form (LATE-EVAL-ONLY in my original
compiler cleanup proposal.)
Rob
∂23-Feb-89 1229 CL-Compiler-mailer top-level, eval-when: it's not too late
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Feb 89 12:28:59 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 544505; Thu 23-Feb-89 15:26:46 EST
Date: Thu, 23 Feb 89 15:26 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: top-level, eval-when: it's not too late
To: Rob.MacLachlan@WB1.CS.CMU.EDU
cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: The message of 23 Feb 89 13:20 EST from Rob.MacLachlan@WB1.CS.CMU.EDU
Message-ID: <19890223202632.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
I haven't read your message carefully yet (I might start reading
Common Lisp mail again around the middle of next week), but a quick
glance through your message makes me think you have forgotten that
Common Lisp has macros. If there were no macros, which inherently
require compile time processing, and if there was no need for the
ability for users to create their own facilities that use compile
time processing, then compile-file would not be semantically
different from evaluation and I would agree with you.
∂23-Feb-89 1316 Common-Lisp-Object-System-mailer CLOS defining macros & compilation
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Feb 89 13:15:57 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA23821; Thu, 23 Feb 89 14:14:01 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10372; Thu, 23 Feb 89 14:13:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902232113.AA10372@defun.utah.edu>
Date: Thu, 23 Feb 89 14:13:57 MST
Subject: CLOS defining macros & compilation
To: cl-compiler@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
This is an attempt to summarize the problems that have been raised so
far about the compilation semantics of the various CLOS defining
macros.
The descriptions of the expansions of the DEFCLASS, DEFMETHOD, and
DEFGENERIC macros in the meta-object protocol document specify that
subforms be evaluated at compile-time in the lexical environment in
which the defining macro appears, which is not fully defined until
run-time. The obvious solution to this problem is to say that the
compile-time evaluation happens only when the defining macro call
appears at top-level, the same as for all the other defining macros.
However, some people have questioned whether compile-time evaluation
is even necessary at all, especially in the case of DEFMETHOD and
DEFGENERIC.
The meta-object protocol does not say anything about whether
DEFINE-METHOD-COMBINATION has compile-time side-effects.
The CLOS spec assumes that compile-time class and method definitions
are made available through a remote lexical environment object. The
full implications of this are not well-understood and we have little
or no experience with actual implementation.
The descriptions of the expansions of the DEFCLASS, DEFMETHOD, and
DEFGENERIC macros in the meta-object protocol document assume that
lexical environment objects received with &ENVIRONMENT have indefinite
extent. Some people have argued that it ought to be legal for
environment objects to have only dynamic extent (issue
MACRO-ENVIRONMENT-EXTENT). There have also been concerns expressed
about how COMPILE-FILE should "clean up" the class structure to remove
definitions made during compilation.
Now, as to what I suggest we do about all of this.
I believe that there are enough serious problems with the compilation
semantics presented in the meta-object protocol document distributed
before the January meeting that it would be a mistake to try to
standardize that behavior. It does not appear that any alternate
proposal is forthcoming from the CLOS committee in time for us to make
the March 15th deadline (that's less than 3 weeks away, folks).
To me it appears that the only practical solution for the near term is
a minimal proposal that leaves many aspects of the behavior explicitly
vague. (Basically, that DEFCLASS makes the class name recognizable as
a valid type name in subsequent declarations, but leaving unspecified
whether or not real class, method, etc. objects are fully defined at
compile-time.) It may well happen that at some point the MOP
compilation semantics will be fixed and the behavior can be specified
more tightly, but I don't see any sign of that happening within the
next couple of weeks.
I think that one of the things we must leave explicitly vague is the
use of remote lexical environment objects to contain compile-time
definitions. Proposal COMPILE-TIME-HANDLING-OF-TOP-LEVEL-FORMS allows
implementations considerable freedom in how other kinds of definitions
(DEFMACRO, DEFSTRUCT, etc.) are made available to the compiler; it
says only that such definitions *are* made available. Why not do the
same thing for the CLOS defining macros? I certainly don't want to
discourage people from continuing to pursue the issues involved, but
the work seems too experimental yet at the stage to fall into the
domain of a standards committee.
-Sandra
-------
∂23-Feb-89 1412 CL-Cleanup-mailer Potential issue: MACRO-SPECIAL-FORMS
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 23 Feb 89 14:10:39 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa11723; 23 Feb 89 22:00 GMT
Date: Thu, 23 Feb 89 22:00:42 GMT
Message-Id: <25126.8902232200@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Potential issue: MACRO-SPECIAL-FORMS
To: cl-compiler@sail.stanford.edu, cl-cleanup@sail.stanford.edu
There's a problem that's been bothering me from time-to-time, and
I would like to have it cleared up one way or another. I've actually
mentioned it several times in the context of other issues, but it
never caught on.
I won't put it in official issue format yet, but I am certainly
willing to do so. One problem is that I'm not sure whether the right
forum is Cleanup or Compiler.
Problem:
On page 57, CLtL explains that the list of special forms is kept small
"because any program-analyzing program must have special knowledge
about every type of special form." It goes on to say "Such a program
needs no special knowledge about macros because it is simple to expand
the macro and operate on the resulting expansion."
Indeed, although an implementation is permitted to implement as a
special form any construct described by CLtL as a macro, it is
required to provide "an equivalent macro definition" [also p 57].
However, the implementation note on page 58 explicitly allows the
macro definition to produce an expansion that contains implementation-
dependent special forms, thus making the requirement for an equivalent
macro an empty one.
Consequently, program-analyzing programs are not promised anything of
value.
Proposal:
Remove the permission granted by the implementation note on page 57.
Require that the macro expansion of any construct described as a macro
in Common Lisp not contain any implementation-specific special forms.
A secondary problem:
The implementation note on page 58 claims "there is no problem
with a macro expansion containing calls to implementation-dependent
functions."
Unfortunately, that is not quite true. For example, a special form
(sf . args) might expand to (do-an-sf '(sf . args)), where do-an-sf
is an implementation-dependent function. Such functions are
essentially special forms in disguise.
A program-analyzing program learns nothing of value from such an
expansion.
Not quite a Proposal:
This one is harder, because it is difficult (and perhaps impossible?)
to precisely characterize the class of acceptable functions.
The basic goal is that the intent of the macro definition should be
evident in the expansion. Subexpressions of the macro call that are
identified syntactically as forms should appear as forms in the
expansion, variables should appear as variables, and so on. But we
can't say they must appear only as forms, variables, and so on; so
it's not clear that the goal is an attainable one. There are
presumably other problems as well.
Consequences of non-adoption:
We would have to say that program-analyzing programs potentially
require (and therefore, to be portable, require) special knowledge
about every construct described as a special form or as a macro
in the definition of Common Lisp.
I would like to eliminate the first problem even if we can't
handle the second.
-- Jeff
∂23-Feb-89 1446 CL-Compiler-mailer Potential issue: MACRO-SPECIAL-FORMS
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Feb 89 14:45:51 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 544726; Thu 23-Feb-89 17:43:20 EST
Date: Thu, 23 Feb 89 17:43 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Potential issue: MACRO-SPECIAL-FORMS
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
cc: cl-compiler@sail.stanford.edu, cl-cleanup@sail.stanford.edu
In-Reply-To: <25126.8902232200@subnode.aiai.ed.ac.uk>
Message-ID: <890223174301.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Thu, 23 Feb 89 22:00:42 GMT
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
...
The implementation note on page 58 claims "there is no problem
with a macro expansion containing calls to implementation-dependent
functions."
Unfortunately, that is not quite true. For example, a special form
(sf . args) might expand to (do-an-sf '(sf . args)), where do-an-sf
is an implementation-dependent function. Such functions are
essentially special forms in disguise.
A program-analyzing program learns nothing of value from such an
expansion.
...
This part is not true and weakens your earlier point (which I think is
well-taken). For example, the implementation of Flavors used by Cloe
uses a code-walker to implement SYMBOL-MACROLET and that code-walker is
written entirely in portable Common Lisp. What is important to that
code walker (and a whole class of code walkers like it) is that it know
what parts of something are `evaluated normally,' what parts are
`evaluated specially,' and what parts are `not evaluated.' For example,
if UNWIND-PROTECT were not a standard special form but was added by some
implementation with a macroexpander that turned
(UNWIND-PROTECT (FOO) (BAR))
into
(SI::UNWIND-PROTECT-FUNCTION #'(LAMBDA () (FOO))
#'(LAMBDA () (BAR)))
this would be fine. While you're right when you say I don't "learn" anything
from examining the latter form, you're wrong when you fail to observe that
I can `walk' the latter form reliably, while I cannot walk the former.
The reason this is so is because no function in Common Lisp is prohibited
from doing magic things that no user could ever possibly hope to write.
That shouldn't be so surprising. After all, it's not just my function above
that has this property, but also other usually-seen-as-ordinary functions
like OPEN or CAR. I can't write them in Common Lisp either, after all.
Certainly there are applications that need to have a deeper understanding
of what special forms do, but there's really no hope for such applications.
Indeed, such applications probably have to have specialized knowledge about
DO as well -- and cannot even depend on its macro expander to provide "insight".
...
I would like to eliminate the first problem even if we can't
handle the second.
...
I suggest that to do this you should drop the second cause so that arguments
against it don't end up detracting from the first.
By the way, in considering the alternatives, please keep in mind that another
possible solution (besides disallowing macros expanding into implementation-specific
special forms) is to define a code-walker interface and facility for extending same
so that extending the language to have new special forms doesn't cause a breakdown
in the ability to do code-walking. I think it's reasonable to describe this as
beyond the scope of what we have time or resources to do at this point, but I
wouldn't want mention of the option to be omitted altogether.
∂23-Feb-89 1502 CL-Cleanup-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Feb 89 15:02:16 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA27356; Thu, 23 Feb 89 16:00:20 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10426; Thu, 23 Feb 89 16:00:18 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902232300.AA10426@defun.utah.edu>
Date: Thu, 23 Feb 89 16:00:17 MST
Subject: Re: Potential issue: MACRO-SPECIAL-FORMS
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: cl-compiler@sail.stanford.edu, cl-cleanup@sail.stanford.edu
In-Reply-To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Thu, 23 Feb 89 22:00:42 GMT
I've been burned by this problem more than once myself. A few
additional observations:
I just recently ran into a problem with Lucid Lisp expanding things
like DEFUN into something that included (FUNCTION (NAMED-LAMBDA ...)).
In other words, it's a valid Common Lisp special form but not valid
Common Lisp syntax for that form. Perhaps a better restriction than
"macros must not expand into implementation-dependent special forms"
would be "macros must expand into code which has Common Lisp syntax".
Once I ran into a problem in VaxLisp where one of the multiple value
macros was treated as a special form by the compiler. It
macroexpanded into some really terrible code and I was getting a
noticible performance hit by having my codewalker just blindly
expanding it. Even though the macro definition was semantically
correct, I ended up adding a whole bunch of macros to the list of
things my codewalker treated as "special forms". I suspect that other
implementations do similar things -- I know my A-Lisp compiler also
treated some of the multiple value macros specially as well.
It ought to be OK for things that are documented as special forms to be
implemented as macros that expand into other implementation-dependent
special forms, since code analyzers are expected to have special
knowledge about them instead of using the macro expansion.
-Sandra
-------
∂23-Feb-89 1523 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 23 Feb 89 15:22:46 PST
Received: by ti.com id AA10606; Thu, 23 Feb 89 17:20:02 CST
Received: from Kelvin by tilde id AA19529; Thu, 23 Feb 89 17:08:12 CST
Message-Id: <2813267244-7521051@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 23 Feb 89 17:07:24 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU, Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
In-Reply-To: Msg of Fri, 10 Feb 89 18:32 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL):
I don't think this one is acceptable because it changes the conceptual
meaning of the EVAL and LOAD situations, even if it may not alter the
behavior in common usage.
> Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS):
>
> As in GENERALIZE-EVAL, but rename the EVAL keyword to :EXECUTE,
> the COMPILE keyword to :COMPILE-TOPLEVEL, and LOAD keyword to
> :LOAD-TOPLEVEL.
>
> Deprecate the use of keywords EVAL, COMPILE, and LOAD to EVAL-WHEN.
> For compatibility, they are supported in EVAL-WHEN
> at top-level, but their meaning is not defined elsewhere.
Now this has possibilities. After all the discussion on this issue, I
am beginning to think that the only way to reach a good solution is to
junk the old situation names and define new ones so that we don't have
to worry about maintaining compatibility with existing rules that don't
make too much sense and aren't stuck with names that are more misleading
than mnemonic.
However, if we are willing to take that big a step, then I'm not sure
that this is the right set of situations. In particular, I'm having
trouble imagining what the :LOAD-TOPLEVEL situation would be used for.
Here are the situations that I think would be useful:
:EXECUTE - execute at the normal time [as though there wasn't any
EVAL-WHEN].
:COMPILE-TOP-LEVEL - execute at compile time if at top level, with a
preference for side-effects to be recorded in the
compile-time environment instead of the resident
environment.
For example, this would be used to install the definition of a
macro for use later in the file.
:COMPILE-ALWAYS - execute in a null lexical environment at compile
time whether at top level or not.
This would be less common, but could still be useful for things
like noticing that a definition of a function exists in order to
suppress warnings about calls to an undefined function. That
would be meaningful even if you didn't actually install the
definition because it doesn't appear at top level.
:COMPILE-PERMANENT - execute at compile time if at top level,
side-effecting the resident environment.
For example, you would want to use this for operations that
create or alter a package.
The rationale probably should point out that all of this assumes that
distinctions between evaluated and compiled code are not portable, and
hence the standard doesn't need to specify how to do that. An
additional reason for changing the situation names is so that
implementations could continue to use the EVAL and LOAD situations to
distinguish these for doing implementation-specific things.
Other comments:
> ;; #4: This always does nothing. It simply returns NIL.
>
> (EVAL-WHEN (COMPILE)
> (EVAL-WHEN (COMPILE)
> (PRINT 'FOO4)))
This case still bothers me. Even if it is not something that would
commonly be done and the behavior is the consequence of otherwise
useful rules, this still seems completely counter-intuitive.
> Date: Sun, 12 Feb 89 16:40 EST
> From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
...
> For example, it doesn't matter that
> (EVAL-WHEN (COMPILE) (EVAL-WHEN (COMPILE) ...))
> doesn't execute anything. The reason is that you probably never really
> right this. Probably what really happens is Person 1 writes:
> (DEFMACRO FOO () `(EVAL-WHEN (COMPILE) ...))
> and Person 2 writes:
> (EVAL-WHEN (COMPILE) (FOO))
> Now all that's important is that Person 1 has asked himself the question
> "Should FOO do anything when in a non-top-level position?" If he has answered
> "Yes" to that, then he has made an extremely obvious programming error, and
> no complicated reasoning about nested EVAL-WHEN's is needed to notice it.
> If he has answered "No", then he presumably has a good reason. Then we have
> to ask, did the person implementing "FOO" document that the form was legitimate
> anywhere or only at top-level or what? If he documented that FOO was appropriate
> to use anywhere, and he still used only the COMPILE option, then he must have
> somehow proven to himself that the contract of FOO could be satisfied without
> any work in some circumstances. Now the only remaining question is, did the
> user of FOO read and use that documentation properly. Since we've agreed that
> the doc says he could use it anywhere, then regardless of what
> (EVAL-WHEN (COMPILE) (EVAL-WHEN (COMPILE) ...))
> -does-, we know that it is doing what is intended.
I see two problems with this line of argument:
(1) It is not obvious why the body of the outer (EVAL-WHEN (COMPILE)
...) should not be considered to be top level.
(2) The primary reason that person 1 used EVAL-WHEN was that they wanted
it to happen at compile time; considerations of top-level-ness is a
secondary detail. Person 2 also wants it to happen at compile time. So
this appears to be a case of two rights make a wrong.
> Date: Sun, 12 Feb 89 17:11:16 MST
> From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
> To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> Cc: sandra%defun@cs.utah.edu, CL-Compiler@SAIL.Stanford.EDU,
> Moon@STONY-BROOK.SCRC.Symbolics.COM
> In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Sun, 12 Feb 89 16:40 EST
>
> I don't have any quibble with the behavior of the examples you cite.
> However, you still haven't said anything to justify the behavior of
> your proposal under example *I* cited in my previous message, namely,
> why
>
> (eval-when (load)
> (defmacro foo ...))
>
> should cause FOO to be defined in the compile-time environment even when
> the user explicitly specified that the macro only needs to be defined at
> load time.
I agree that this should do what is expected.
> Date: Mon, 13 Feb 89 13:39 EST
> From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
> To: sandra%defun@cs.utah.edu
> Cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU,
> Moon@STONY-BROOK.SCRC.Symbolics.COM
> In-Reply-To: <8902130011.AA02791@defun.utah.edu>
...
> Among other things, because it is incompatible with CLtL. p70 says:
>
> If the situation LOAD is specified
> then if the situation COMPILE is also specified
> then ...
> else process each of the forms in the body in not-compile-time mode.
>
> `not-compile-time' mode must see DEFMACRO because the previous page says that
> all top-level forms are defaultly processed in not-compile-time mode, which
> means that DEFMACRO is normally noticed by the compiler when in that mode.
Which is a reason for deprecating the "LOAD" situation and defining new
ones that can be defined better.
> Getting back to EVAL-WHEN, though, our semantics allow you to keep something
> from being `noticed' by the compiler by just putting it in a non-top-level
> position.
> (LET () (DEFMACRO FOO ...))
> is the easiest way to do that right now, but you can also write:
> (DEFUN INIT ()
> (DEFMACRO ...)
> (DEFMACRO ...) ...)
> (INIT)
Sure, but controlling the time of execution is what EVAL-WHEN is
supposed to be for, so it seems odd that it works in some cases but not
others.
> Also, as a matter of pragmatics, I find that it is -extremely- rare to
> want DEFMACRO to not be seen at compile time but rather only to be seen at
> load time.
Agreed; the real problem is that EVAL-WHEN allows you to say things that
don't really mean what they appear to mean.
∂23-Feb-89 1525 CL-Compiler-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Feb 89 15:25:25 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 544794; Thu 23-Feb-89 18:22:53 EST
Date: Thu, 23 Feb 89 18:22 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Potential issue: MACRO-SPECIAL-FORMS
To: sandra%defun@cs.utah.edu
cc: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK,
cl-compiler@sail.stanford.edu, cl-cleanup@sail.stanford.edu
In-Reply-To: <8902232300.AA10426@defun.utah.edu>
Message-ID: <890223182235.1.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Thu, 23 Feb 89 16:00:17 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
...
Once I ran into a problem in VaxLisp where one of the multiple value
macros was treated as a special form by the compiler. It
macroexpanded into some really terrible code and I was getting a
noticible performance hit by having my codewalker just blindly
expanding it. Even though the macro definition was semantically
correct, I ended up adding a whole bunch of macros to the list of
things my codewalker treated as "special forms". I suspect that other
implementations do similar things -- I know my A-Lisp compiler also
treated some of the multiple value macros specially as well.
Just for the record, this is something that I had worried about with the
Cloe Flavors code walker running under Symbolics Genera, but I found
that the Genera compiler had optimizers for many of the scary-looking
idioms that these macros produced, so the compiled code was identical
regardless of whether I compiled the expanded or unexpanded expression.
I have to say that this is as it should be from a `reasonable compiler'
anyway since if there are two seemingly equivalent ways to do something
and the language spec itself does not suggest that one is likely to be
more efficient than the other, the programmer should not have to fear that
just because he didn't say the right incantation, he won't get efficient
code.
...
It ought to be OK for things that are documented as special forms to be
implemented as macros that expand into other implementation-dependent
special forms, since code analyzers are expected to have special
knowledge about them instead of using the macro expansion.
This is a very good point. However, if it were to become accepted
theory, though, it should be explicitly stated. It affects whether I do
a MACROEXPAND-1 or a MACROEXPAND after the call to SPECIAL-FORM-P.
Normally I consider it safe to do either -- and slightly less cumbersome
to do the latter. However, your remark suggests that I might be safer
doing the former.
∂23-Feb-89 1519 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 23 Feb 89 15:19:44 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA04040; Thu, 23 Feb 89 15:20:06 PST
Received: from suntana.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA03709; Thu, 23 Feb 89 15:16:36 PST
Received: from localhost by suntana.sun.com (4.0/SMI-4.0)
id AA18092; Thu, 23 Feb 89 15:17:04 PST
Message-Id: <8902232317.AA18092@suntana.sun.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
Subject: Re: CLOS defining macros & compilation
In-Reply-To: Your message of Thu, 23 Feb 89 14:13:57 -0700.
<8902232113.AA10372@defun.utah.edu>
Date: Thu, 23 Feb 89 15:16:58 PST
From: kempf@Sun.COM
>vague. (Basically, that DEFCLASS makes the class name recognizable as
>a valid type name in subsequent declarations, but leaving unspecified
>whether or not real class, method, etc. objects are fully defined at
>compile-time.) It may well happen that at some point the MOP
This is going to put a crimp in the usual style of OO programming, namely
to define classes at the top of a file, then the methods applicable to
them thereafter. What you're saying is that this style would be
potentially nonportable.
jak
∂23-Feb-89 1532 Common-Lisp-Object-System-mailer CLOS defining macros & compilation
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 23 Feb 89 15:32:22 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA00718g; Thu, 23 Feb 89 15:25:39 PST
Received: by challenger id AA09808g; Thu, 23 Feb 89 15:21:13 PST
Date: Thu, 23 Feb 89 15:21:13 PST
From: Patrick Dussud <dussud@lucid.com>
Message-Id: <8902232321.AA09808@challenger>
To: kempf@Sun.COM
Cc: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
In-Reply-To: kempf@Sun.COM's message of Thu, 23 Feb 89 15:16:58 PST <8902232317.AA18092@suntana.sun.com>
Subject: CLOS defining macros & compilation
Date: Thu, 23 Feb 89 15:16:58 PST
From: kempf@Sun.COM
>vague. (Basically, that DEFCLASS makes the class name recognizable as
>a valid type name in subsequent declarations, but leaving unspecified
>whether or not real class, method, etc. objects are fully defined at
>compile-time.) It may well happen that at some point the MOP
This is going to put a crimp in the usual style of OO programming, namely
to define classes at the top of a file, then the methods applicable to
them thereafter. What you're saying is that this style would be
potentially nonportable.
jak
Not necessarily. Flavors classes do not get fully defined at compile time. The
compiler notices so much about them so methods can be added to them, and method
combination can be executed. The style that we all use and love can me made
portable, but what happens in the brain of the compiler, and the CLOS
interpreter during a compile-file might not be specified.
I think that's what Sandra is proposing.
Patrick.
∂23-Feb-89 1546 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 23 Feb 89 15:46:19 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA05145; Thu, 23 Feb 89 15:46:48 PST
Received: from suntana.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA04970; Thu, 23 Feb 89 15:43:18 PST
Received: from localhost by suntana.sun.com (4.0/SMI-4.0)
id AA18162; Thu, 23 Feb 89 15:43:40 PST
Message-Id: <8902232343.AA18162@suntana.sun.com>
To: Patrick Dussud <dussud@lucid.com>
Cc: kempf@Sun.COM, sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
Subject: Re: CLOS defining macros & compilation
In-Reply-To: Your message of Thu, 23 Feb 89 15:21:13 -0800.
<8902232321.AA09808@challenger>
Date: Thu, 23 Feb 89 15:43:37 PST
From: kempf@Sun.COM
>Not necessarily. Flavors classes do not get fully defined at compile time. The
>compiler notices so much about them so methods can be added to them, and method
>combination can be executed. The style that we all use and love can me made
>portable, but what happens in the brain of the compiler, and the CLOS
>interpreter during a compile-file might not be specified.
>I think that's what Sandra is proposing.
I guess defining the type at compile time would be OK, but I think the
spec will have to be changed to allow method definition on the type
rather than the class. Technically, the compiler should only need
the type and not the class anyway. This might have ramifications, however,
so it's best to think it over.
jak
∂23-Feb-89 1550 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
Received: from ti.com by SAIL.Stanford.EDU with TCP; 23 Feb 89 15:50:12 PST
Received: by ti.com id AA10726; Thu, 23 Feb 89 17:49:15 CST
Received: from Kelvin by tilde id AA21083; Thu, 23 Feb 89 17:43:00 CST
Message-Id: <2813269367-7648607@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 23 Feb 89 17:42:47 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
Subject: Re: CLOS defining macros & compilation
In-Reply-To: Msg of Thu, 23 Feb 89 14:13:57 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> The descriptions of the expansions of the DEFCLASS, DEFMETHOD, and
> DEFGENERIC macros in the meta-object protocol document assume that
> lexical environment objects received with &ENVIRONMENT have indefinite
> extent.
Not really, unless you've noticed something I missed. Some objects in
the environment (class definitions in particular) have an extent
corresponding to the duration of the invocation of COMPILE-FILE, but the
environment objects themselves, as received by a macro, do not need to
be used outside the extent of that macro invocation.
∂23-Feb-89 1558 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Feb 89 15:57:52 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA28812; Thu, 23 Feb 89 16:55:49 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10511; Thu, 23 Feb 89 16:55:46 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902232355.AA10511@defun.utah.edu>
Date: Thu, 23 Feb 89 16:55:45 MST
Subject: Re: CLOS defining macros & compilation
To: kempf@Sun.COM
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
In-Reply-To: kempf@Sun.COM, Thu, 23 Feb 89 15:16:58 PST
> Date: Thu, 23 Feb 89 15:16:58 PST
> From: kempf@Sun.COM
>
> This is going to put a crimp in the usual style of OO programming, namely
> to define classes at the top of a file, then the methods applicable to
> them thereafter. What you're saying is that this style would be
> potentially nonportable.
That certainly isn't my intent -- I want to legitimize current
programming practice while glossing over the details of how it's
actually implemented.
I can't find any reference in 88-002R to whether classes named as
parameter specializers in a DEFMETHOD must be defined before the
DEFMETHOD is "evaluated", much less in advance of when the DEFMETHOD
is macroexpanded. (It says a parameter specializer is a symbol that
names a class.) The MOP document does seem to imply that there must be
real class objects defined at compile time, but only so it can create
a real method object at compile time. We could put in an explicit
statement that classes that appear as DEFMETHOD's parameter
specializers must be known at compile time and that compiling a
DEFCLASS will make the class name known to the compiler for this
purpose. We probably need to say something similar about class names
defined by DEFSTRUCT as well, right?
We could also put in a statement that DEFCLASS makes the class name
known to the compiler so it can appear as a superclass in another
DEFCLASS, analogous to the language about the DEFSTRUCT :INCLUDE
option in proposal COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS. But
88-002R already says that superclasses don't need to be defined at all
if the metaclass is STANDARD-CLASS, so this might be unnecessary.
-Sandra
-------
∂23-Feb-89 1607 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Feb 89 16:07:39 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA29059; Thu, 23 Feb 89 17:05:38 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10531; Thu, 23 Feb 89 17:05:36 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902240005.AA10531@defun.utah.edu>
Date: Thu, 23 Feb 89 17:05:35 MST
Subject: Re: CLOS defining macros & compilation
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Thu, 23 Feb 89 17:42:47 CST
> Date: Thu, 23 Feb 89 17:42:47 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> > The descriptions of the expansions of the DEFCLASS, DEFMETHOD, and
> > DEFGENERIC macros in the meta-object protocol document assume that
> > lexical environment objects received with &ENVIRONMENT have indefinite
> > extent.
>
> Not really, unless you've noticed something I missed. Some objects in
> the environment (class definitions in particular) have an extent
> corresponding to the duration of the invocation of COMPILE-FILE, but the
> environment objects themselves, as received by a macro, do not need to
> be used outside the extent of that macro invocation.
We all seem to be converging on the idea that compile-time
side-effects from macros should be handled by having the macro expand
into an (EVAL-WHEN (COMPILE) ...). The MOP document specifies that
the environment object be passed as an argument to calls to FIND-CLASS
(or whatever) that happen as a compile-time side-effect. This implies
that the environment object would have to appear as a quoted constant
in the macro expansion. The proposal to give macro environment
objects dynamic scope would give them dynamic scope *within the macro
function*, which means it would not be legitimate for them to appear
at all in the expansion returned from the macro.
-Sandra
-------
∂23-Feb-89 1646 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Feb 89 16:46:17 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 544911; Thu 23-Feb-89 19:42:37 EST
Date: Thu, 23 Feb 89 19:42 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: Gray@DSG.csc.ti.com
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU,
Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <2813267244-7521051@Kelvin>
Message-ID: <890223194212.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Thanks for taking the time to look this over. I have a few comments on your
proposed list of alternate keywords...
* Pursuant to the discussion I had with Moon prior to drafting version 5,
one way to look at my model is simply:
EVAL = COMPILE + LOAD
Either the left side of the equation is run, or the right side.
There are of course interesting cases where you don't implement one side
or the other of the equation, with some particular purpose in mind. Those
are ok with me as long as they follow from the design, rather than drive
the design.
Using this rule, you can do easy `proofs' to see that you've correctly
implemented all the relevant combinations.
By unifying EVAL and LOAD as simply :EXECUTE in your revised list, you've
destroy an important property of my keywords because you rob me of the
ability to distinguish the `execute' which goes along with not-COMPILE case
from the `execute' which goes along with the COMPILE case.
If you want to provide a `total' :EXECUTE, you must still provide
at least :EXECUTE-NON-TOP-LEVEL, :COMPILE-TOP-LEVEL, and :LOAD-TOP-LEVEL.
Pick whatever names you like, but that level of distinction is extremely
important.
* As for :COMPILE-ALWAYS, an example might help. But I think you've isolated
a potentially `real' point of disagreement on goal (vs solution, which we've
been mostly discussing) when you say
``... This would be less common, but could still be useful for things
like noticing that a definition of a function exists in order to
suppress warnings about calls to an undefined function. ...''
I very strongly believe not only that this should not be a goal, but
that it should be a goal to prohibit the compiler from being allowed to
take such action.
If I have a function that is going to reliably define another function
and the compiler doesn't notice it, what I want is a way to declare
(i.e. proclaim) to the compiler that I promise to deliver that function
in time. What I do -not- want is for the compiler to not warn me in the
absence of such a declaration. It might be that I really didn't
realize that the thing would never get executed -- the compiler does
me no favors by failing to alert me to this potential problem in the
absence of the aforementioned proclamation.
If you think otherwise, then the problem is more serious than I was
assuming because we don't even have the same abstract goals in mind.
* As for :COMPILE-PERMANENT, I could not convince myself that it would not
be invasive to proprietary models of CL. What if someone really implements
a compiler such that COMPILE-FILE of a file that creates package FOO
does not leave package FOO present. It's my impression that what KCL
does amounts to this by running the file compiler in a separate
environment, but I can imagine totally different implementations
that achieve the same effect.
* Re: ``The primary reason that person 1 used EVAL-WHEN was that they wanted
it to happen at compile time; considerations of top-level-ness is a
secondary detail. Person 2 also wants it to happen at compile time.
So this appears to be a case of two rights make a wrong.''
This interpretation is nonsensical to me. If we documented EVAL-WHEN as in
v5, no one who understands what EVAL-WHEN does could have been party to
such a scenario as you describe. You either believe in the whole definition
of a primitive or you don't use it.
You wouldn't realistically expect me to give credence to a claim that SETQ
is buggy just because someone does
(DEFUN FOO () (SETQ *FOO* 3) (BAR))
rather than
(DEFUN FOO () (LET ((*FOO* 3)) (BAR)))
just because he thought the issue of global side-effect was `secondary'
do you?
If we adopt the v5 semantics of EVAL-WHEN, there can't be a presentation in
the documentation of `primary reasons' and `secondary reasons.' All you can
do is to present the semantics. Hopefully you suggest an intuition (such as
I did at the start of this message) but that intuition should not hide the
full semantics of the operation.
* Re: ``... controlling the time of execution is what EVAL-WHEN is
supposed to be for, so it seems odd that it works in some cases
but not others.''
I think this should not really be seen as an oddity. It doesn't do the job
of LOAD-TIME-VALUE. Does that seem odd to you? It used to seem odd to me,
but I've changed my opinion. I think that the two primitives do very
different things (yet they both control time of execution).
It also -- quite reasonably -- doesn't (and in fact, can't) do the job of #. .
In a strict philosophical sense, all of programming is really just about
changing the time at which execution occurs. Maybe you just need a new intuition
about what EVAL-WHEN does (or EVAL-WHEN needs a new name :-).
∂23-Feb-89 1650 CL-Compiler-mailer remote environments
Received: from ti.com by SAIL.Stanford.EDU with TCP; 23 Feb 89 16:48:49 PST
Received: by ti.com id AA11038; Thu, 23 Feb 89 18:48:24 CST
Received: from Kelvin by tilde id AA22434; Thu, 23 Feb 89 18:38:13 CST
Message-Id: <2813272681-7847725@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 23 Feb 89 18:38:01 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Common-Lisp-Object-System@SAIL.Stanford.edu
Cc: CL-Compiler@SAIL.Stanford.edu
Subject: remote environments
I think it might help to focus the discussion about remote environments
and meta object programming if we had a clearer picture of what the
goals are. The basic question is what kinds of things can be defined and
then used during compilation of the same file that defines them, and
what restrictions might apply.
DEFCLASS
* Can the class be used as a superclass of a later DEFCLASS? [clearly yes]
* Can it be used as a specializer in a DEFMETHOD? [clearly yes]
* Can a MAKE-INSTANCE be done by a macro expander, DEFCONSTANT, or "#."?
- If so, do initforms have access to macros and constants defined
earlier in the file?
* Can the class be used as the :METACLASS option of a later DEFCLASS?
- Can that second class be instantiated?
* Can it be used as the :GENERIC-FUNCTION-CLASS option of a
DEFGENERIC, GENERIC-FUNCTION, GENERIC-FLET, or GENERIC-LABELS?
* Can it be used as the :METHOD-CLASS option of a DEFGENERIC etc.?
- Can DEFMETHODs then be done for that generic function?
DEFGENERIC
* Referenced by later DEFMETHOD? [clearly yes]
* Is the function defined such that it can be called at compile time?
DEFMETHOD
* Can it be invoked at compile-time?
* In particular, will methods added to standard generic functions be
invoked by the system at compile time?
DEFINE-METHOD-COMBINATION
* Used in a later DEFGENERIC?
- Callable at compile-time?
Are there other interactions that need to be considered?
I think that the standard could take a simple, minimal, approach that
would still satisfy the most common usages. Suppose we said:
DEFCLASS
If it appears at top-level, then the class name is defined for use as
a type specifier or method specializer. It can also be used as a
superclass of a later DEFCLASS since they don't have to be defined
before being referenced anyway. The class object can be obtained by
calling FIND-CLASS with an environment argument, but it can only be
used in ways that do not require the class to be finalized. For
example, one could ask for its CLASS-DIRECT-SUPERCLASSES, but not its
CLASS-PRECEDENCE-LIST. Other uses, which could involve the need to
instantiate the class, could not be portably done in the same file
without wrapping an (EVAL-WHEN (EVAL COMPILE LOAD) ...) around the
DEFCLASS. Implementations would be free to support compile-time
instantiation as an extension. One way to look at this would be to
say that it is implementation-dependent whether FINALIZE-INHERITANCE
works or signals an error when given a class defined in the
compile-time environment.
DEFGENERIC
The attributes of the generic function that affect DEFMETHOD will be
recorded for use by definitions of methods for that generic function
later in the file. This includes the lambda-list and method class.
It is implementation-dependent whether this is actually put in the
form of a generic function object and whether other operations on that
generic function are possible at compile-time.
DEFMETHOD
Method definitions are not required to have any compile-time
side-effects, but the compiler may warn about things like undefined
specializer classes or non-congruent lambda-lists. ADD-METHOD is not
invoked at compile-time unless forced by using EVAL-WHEN.
DEFINE-METHOD-COMBINATION
No compile-time side-effect is required. The new combination can
still be referenced in DEFGENERICs and DEFMETHODs later in the file
since the definition is not really needed until the generic function
is called and an effective method needs to be computed. A compiler
could, however, notice what combination names have been defined and
issue a warning on a DEFGENERIC with an undefined combination
or a DEFMETHOD using an undefined qualifier.
∂23-Feb-89 1704 CL-Compiler-mailer Re: CLOS defining macros & compilation
Received: from ti.com by SAIL.Stanford.EDU with TCP; 23 Feb 89 17:04:17 PST
Received: by ti.com id AA11088; Thu, 23 Feb 89 19:03:33 CST
Received: from Kelvin by tilde id AA22569; Thu, 23 Feb 89 18:48:42 CST
Message-Id: <2813273316-7885881@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 23 Feb 89 18:48:36 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu
Subject: Re: CLOS defining macros & compilation
In-Reply-To: Msg of Thu, 23 Feb 89 17:05:35 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> ... This implies
> that the environment object would have to appear as a quoted constant
> in the macro expansion. The proposal to give macro environment
> objects dynamic scope would give them dynamic scope *within the macro
> function*, which means it would not be legitimate for them to appear
> at all in the expansion returned from the macro.
Oh, OK. That still isn't quite indefinite extent though, more like the
extent of the compiler's processing of that lexical context. I'm just
concerned that the extent not extend beyond the time that COMPILE-FILE
finishes, and that it should not be valid to query an environment for
lexical context information after the compiler is no longer in that same
context. The latter restriction is so that I don't have to redesign my
compiler to keep all of its data in the form of environment objects, but
can define environment accessors that pick up the information from
wherever it currently happens to be kept.
∂23-Feb-89 1746 CL-Compiler-mailer Re: remote environments
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Feb 89 17:46:12 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA01793; Thu, 23 Feb 89 18:44:16 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10622; Thu, 23 Feb 89 18:44:12 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902240144.AA10622@defun.utah.edu>
Date: Thu, 23 Feb 89 18:44:11 MST
Subject: Re: remote environments
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: Common-Lisp-Object-System@SAIL.Stanford.edu, CL-Compiler@SAIL.Stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Thu, 23 Feb 89 18:38:01 CST
Thanks for putting together a list of all the questions involved. I
can't claim to be an expert on the subject, but perhaps my answers
would be useful as a representation of the expectations of a naive
user with few preconceived notions.
> DEFCLASS
> * Can the class be used as a superclass of a later DEFCLASS? [clearly yes]
> * Can it be used as a specializer in a DEFMETHOD? [clearly yes]
So far, so good.
> * Can a MAKE-INSTANCE be done by a macro expander, DEFCONSTANT, or "#."?
Probably not. We allow other kinds of definitions seen by the
compiler (macros, for example), to be hidden somewhere where they are
not visible in these circumstances. If you really want the class to
be fully defined at compile time, you should wrap the definition in an
(EVAL-WHEN (EVAL COMPILE LOAD)...).
> * Can the class be used as the :METACLASS option of a later DEFCLASS?
> - Can that second class be instantiated?
I'm not sure on this one. I'm inclined to think that users would put
the metaclass definition and all its methods off in a separate file
anyway, so I don't see any compelling reason to -require- that a class
be usable as a metaclass in the same file it is defined in.
> * Can it be used as the :GENERIC-FUNCTION-CLASS option of a
> DEFGENERIC, GENERIC-FUNCTION, GENERIC-FLET, or GENERIC-LABELS?
> * Can it be used as the :METHOD-CLASS option of a DEFGENERIC etc.?
> - Can DEFMETHODs then be done for that generic function?
I don't know enough about the issues involved here.
> DEFGENERIC
> * Referenced by later DEFMETHOD? [clearly yes]
Right.
> * Is the function defined such that it can be called at compile time?
I'd have to say no. DEFGENERIC is analagous to DEFUN, and DEFUN only makes
the function definition available at load time.
> DEFMETHOD
> * Can it be invoked at compile-time?
> * In particular, will methods added to standard generic functions be
> invoked by the system at compile time?
No to both questions.
> DEFINE-METHOD-COMBINATION
> * Used in a later DEFGENERIC?
> - Callable at compile-time?
I'm not quite sure what all the issues involved are here. I think
that I would expect a method combination to be usable later on in the
file. To me they seem kind of similar to SETF methods (but maybe
that's just a random coincidence).
> Are there other interactions that need to be considered?
Yes. How about specifying when checks for lambda-list congruence are
made for DEFMETHOD? In particular, suppose I have a generic function
FOO fully defined in the compilation environment, but a file I'm
compiling has a method for FOO with a lambda list that is not
congruent. (Maybe I just fixed the file and I want to recompile and
reload it.) I think it is reasonable for the compiler to issue a
warning but I don't think this is an error or that an error should be
signalled -- that should happen only at run time. This would be in
keeping with the general philosophy of allowing functions to be freely
redefined.
-Sandra
-------
∂23-Feb-89 1834 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ti.com by SAIL.Stanford.EDU with TCP; 23 Feb 89 18:33:50 PST
Received: by ti.com id AA11351; Thu, 23 Feb 89 20:33:16 CST
Received: from Kelvin by tilde id AA24051; Thu, 23 Feb 89 20:21:53 CST
Message-Id: <2813278896-8221153@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 23 Feb 89 20:21:36 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "Kim A. Barrett" <IIM%ECLA@ECLC.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU, eb@LUCID.COM
Subject: Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
In-Reply-To: Msg of Wed 22 Feb 89 16:27:51-PST from Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
> Proposal (SYNACTIC-ENVIRONMENT-ACCESS:ADD-FUNCTIONAL-INTERFACE):
This generally looks like a reasonable proposal. I think that this
could be added to my implementation fairly easily, assuming a suitable
limitation on environment extents.
> The following functions provide information about syntactic environment
> objects. In all of the functions the argument named ENV is a environment, of
> the sort received by the &ENVIRONMENT argument to a macro, or as the
> environment argument for EVALHOOK. In all cases it is an error to supply an
> argument which is not a syntactic environment.
Don't you want to permit passing NIL to signify the global, null
lexical, environment? In fact, since the usefulness of many of these
functions is not limited to local environments, instead of, for example,
ENVIRONMENT-VARIABLE-KIND variable env [Function]
it might be better to have:
VARIABLE-KIND variable &optional env [Function]
> ENVIRONMENT-TARGET env [Function]
>
> This function returns one of the three symbols :EVAL, :COMPILE or
> :COMPILE-FILE, depending on whether the environment is from the interpreter,
> the in-core compiler, or the file compiler. If MACROEXPAND or MACROEXPAND-1
> is called directly without supplying the environment argument, the
> environment passed to any expander functions will have target :EVAL.
I agree with Sandra's comments that ENVIRONMENT-REMOTE-P makes more
sense, and that AUGMENT-ENVIRONMENT needs an argument to specify whether
a remote environment is being created.
> ENVIRONMENT-TYPE variable env [Function]
>
> VARIABLE is a symbol. This function returns the type specifier
> associated with the variable named by the symbol in the environment.
> If no explicit association exists, either by PROCLAIM or DECLARE, then
> the result is the type specifier T.
...
> ENVIRONMENT-FTYPE function env [Function]
>
> FUNCTION is a function name. This function returns the functional type
> specifier associated with the function in the environment, or NIL if there is
> no functional type declaration or proclamation associated with the function.
Since the default type for variables is T, shouldn't the default for
functions be FUNCTION instead of NIL?
I would really like to see the proposal say that these two functions
will return information that the user put in the environment with
AUGMENT-ENVIRONMENT, but is not guaranteed to return anything other than
the default types when given an environment received from the evaluator
or compiler. I don't want the interpreter to have to go to the trouble
of recording type declarations [that it doesn't use] just in case someone
might ask to see them later.
> While an environment argument from EVALHOOK may be used as the environment
> argument for this function, the reverse is not true. It is an error to
> attempt to use the result of AUGMENT-ENVIRONMENT as the environment argument
> for EVALHOOK. The environment returned by AUGMENT-ENVIRONMENT may only be
> used for syntactic analysis.
Presumably it is also valid for MACROEXPAND, or is that included in what
you mean by "syntactic analysis"?
> ENVIRONMENT-PROPERTY env name property &optional default
>
> This function and its SETF method allow the association of arbitrary 'global'
> properties with names. An environment can be thought of as having a local
> property list associated with any name, and this function provides access to
> that property list.
It should be noted that only remote environments have property lists.
In my implementation, the real difference between local and remote
environments is whether storing into it affects the global environment
or is recorded locally. In this proposal, (SETF (ENVIRONMENT-PROPERTY
...) ...) is the only way provided to store into an environment.
∂23-Feb-89 1849 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ti.com by SAIL.Stanford.EDU with TCP; 23 Feb 89 18:49:32 PST
Received: by ti.com id AA11397; Thu, 23 Feb 89 20:48:25 CST
Received: from Kelvin by tilde id AA24339; Thu, 23 Feb 89 20:40:15 CST
Message-Id: <2813280006-8287813@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 23 Feb 89 20:40:06 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: "Kim A. Barrett" <IIM%ECLA@ECLC.USC.EDU>, cl-compiler@SAIL.STANFORD.EDU,
eb@LUCID.COM
Subject: Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
In-Reply-To: Msg of Thu, 23 Feb 89 10:17:49 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> > ENVIRONMENT-PROPERTY env name property &optional default
> >
> > This function and its SETF method allow the association of arbitrary 'global'
> > properties with names. An environment can be thought of as having a local
> > property list associated with any name, and this function provides access to
> > that property list. The association between names and property lists uses
> > EQUAL to match names.
...
> I think this particular item needs more rationale to support it. I
> gather that this is supposed to be the internal mechanism by which
> CLOS hangs information about the class structure off the environment?
> Why does this need to be generalized -- what is wrong with having
> FIND-CLASS be the primitive accessor for this kind of information?
There is precedent for this -- the MIT Lisp Machine system used by TI
and LMI provides a pair of functions called GETDECL and PUTDECL which
can be used to retrieve and store properties in the compile-time
environment. The main difference is that the compiler environment is
implicit rather than being passed in as an argument. I don't know how
many programmers actually use this feature, but since it needs to exist
for the compiler's own use, I don't see any harm in defining a standard
interface for it.
∂23-Feb-89 2103 Common-Lisp-Object-System-mailer CLOS defining macros & compilation
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 23 Feb 89 21:03:45 PST
Received: from Semillon.ms by ArpaGateway.ms ; 23 FEB 89 20:23:23 PST
Date: Thu, 23 Feb 89 20:23 PST
From: Gregor.pa@Xerox.COM
Subject: CLOS defining macros & compilation
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-5.text.newest
In-Reply-To: <8902232113.AA10372@defun.utah.edu>
Message-ID: <19890224042316.2.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Thu, 23 Feb 89 14:13:57 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
I believe that there are enough serious problems with the compilation
semantics presented in the meta-object protocol document distributed
before the January meeting that it would be a mistake to try to
standardize that behavior. It does not appear that any alternate
proposal is forthcoming from the CLOS committee in time for us to make
the March 15th deadline (that's less than 3 weeks away, folks).
No one believes that what is written in draft 10 of the MOP is valid. I
am certainly sorry if that wasn't communicated to you clearly.
A couple of weeks ago I sent a summary analysis to a small group of
people familiar with this problem. My message outlines three courses of
action to take. Among these is a proposal which, while it is minimal in
certain metaobject programming respects, does not restrict ordinary
programming.
My belief is that resolution of this issue cannot proceed until the
EVAL-WHEN issue has been resolved. I have been waiting to see what the
resolution would be on the Symbolics EVAL-WHEN proposal. I haven't said
anything about it before, but that proposal looks right to me. I
believe it has what it would take to implement any of the CLOS behaviors
I outlined to the CLOS group. I don't understand how to provide
reasonable CLOS semantics with the previous propsal.
Once the status of EVAL-WHEN is clear, and I get some more feedback
about the message I sent, I will be able to rewrite the relevant part of
Chapter 3. That rewrite will cover more than what we want to put in the
standard just now, but it will make it clear exactly what the behavior
should be. It will give us a precise model with which to decide exactly
what how much to put in the standard. Then it should be easy to reduce
it to what the compiler committee report should say.
-------
∂23-Feb-89 2236 CL-Compiler-mailer re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 23 Feb 89 22:35:52 PST
Date: Thu 23 Feb 89 21:35:11-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: Rob.MacLachlan@WB1.CS.CMU.EDU
cc: cl-compiler@SAIL.STANFORD.EDU, iim@ECLA.USC.EDU
Message-ID: <12473134681.21.IIM@ECLA.USC.EDU>
I think you may be missing the point of AUGMENT-ENVIRONMENT. First, it can't
possibly introduce retroactive local bindings. It does not side-effect the
environment argument, it returns a new environment which contains everything
in the environment argument, plus the stuff specified by the keyword arguments.
Perhaps an example (as you requested) might help.
I can't think of any really simple examples of using augment-environment off
hand. This is a handler for the LET special form from a hypothetical code
walker. I don't guarantee that the semantics implemented by this function
match any particular varient of Common Lisp, though I was thinking in terms of
X3J13 CL. Also, this example is far from self-contained, containing numerous
references to helper functions which are not described here, though hopefully
they shouldn't be too confusing.
(defun walk-let (form env walk-function)
(multiple-value-bind (body decls)
(extract-declarations (cddr form))
(multiple-value-bind (special-decls type ftype)
(parse-declarations decls)
(let ((vars ())
(inits ()))
(dolist (binding (second form))
(cond ((symbolp binding)
(push binding vars)
(push nil inits))
(t
(push (car binding) vars)
(push (walk-form (cadr binding) env walk-function) inits))))
(let ((lexicals ()))
(dolist (var vars)
(or (member var special-decls)
(variable-globally-special-p var env)
(push var lexicals)))
`(let ,(mapcar #'list (nreverse vars) (nreverse inits))
,@decls
,@(let ((new-env (augment-environment env
:lexical lexicals
:special special-decls
:type type
:ftype ftype)))
(mapcar #'(lambda (form)
(walk-form form new-env walk-function))
body))))))))
Note that this example points out a possible misfeature of the current
description of AUGMENT-ENVIRONMENT. Namely, it might be better to simply
specify all the variables being bound, along with a list of local special
declarations, and let augment-environment figure out the split between lexicals
and specials.
I discussed the question of the extent of these things in a recent message
regarding the WITH-COMPILATION-UNIT issue.
kab
-------
∂23-Feb-89 2355 CL-Compiler-mailer re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 23 Feb 89 23:53:32 PST
Date: Thu 23 Feb 89 21:40:04-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: sandra%defun@CS.UTAH.EDU
cc: cl-compiler@SAIL.STANFORD.EDU, iim@ECLA.USC.EDU
Message-ID: <12473135572.21.IIM@ECLA.USC.EDU>
> From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Thu, 23 Feb 89 10:17:49 MST
>
> One other thing that ought to be clarified here: CLtL p. 145-146 says that
> the &environment argument received by a macro does not have to be the
> complete lexical environment. We should be explicit that we are changing
> this and requiring &environment arguments to contain all of the information
> that the accessors this proposal defines can get at.
Yes and no. The &environment argument need not contain the additional stuff
that an EVALHOOK type environment needs to hold in order to look up the values
associated with bindings. Since the functions in this proposal don't deal with
actial values, only the presence of bindings, the additional stuff isn't
required. Also, I think I would be willing to allow support for the type and
ftype to effectively be optional. This would allow an implementation to simply
ignore all type declarations. Admittedly, this means that user code that wants
to see them won't either.
> I am not so sure that extending this proposal to EVALHOOK environments is
> such a good thing. For one thing, implementations that do some kind of
> preprocessing or partial compilation may not have anything like the kind of
> information this proposal requires available.
I think it is essential. I also think the problem you are describing isn't
real. The information must be present during the preprocessing or parital
compilation phase, and that's where macro expanders are going to get their
hands on an environment and do something with it.
> Another problem is that I am not convinced that this information is really
> all that useful to implementations that want to use EVALHOOK. (For instance,
> I've recently been working on some debugging tools where I've wanted to do
> things like draw pictures of the various lexical contours as nested boxes,
> showing the values of all the local variables in those contours. This
> proposal wouldn't give me the kind of information I need to do that.)
Right, this proposal doesn't give you access to values in an EVALHOOK type
environment. A portable interface to that kind of stuff might not be a bad
thing, but it is outside the scope of this proposal. The filter I've been
using to decide what to include is whether the functionality is needed for your
hypothetical portable file-compiler example.
> > ENVIRONMENT-TARGET env [Function]
> >
> > This function returns one of the three symbols :EVAL, :COMPILE or
> > :COMPILE-FILE, depending on whether the environment is from the
> > interpreter, the in-core compiler, or the file compiler. If MACROEXPAND
> > or MACROEXPAND-1 is called directly without supplying the environment
> > argument, the environment passed to any expander functions will have
> > target :EVAL.
>
> I flamed about this at length when the last version of the proposal came out:
> there are more situations than these in which code may be processed!!! Moon
> suggested that we distinguish only between local and remote environments, and
> rename this function ENVIRONMENT-REMOTE-P. I think that would make a lot more
> sense.
Can you name some other situations? Note that I regard :COMPILE-FILE as
refering not only to the implementation's compiler, but also to the
hypothetical portable file-compiler. Perhaps I should make that more explicit.
This gets into the stuff I'm thinking about with regard to
WITH-COMPILATION-UNIT, which I haven't fully worked out and gotten it written
down yet.
> > Some function names may refer to both a global macro and a global special
> > form. In such a case, the macro takes precedence, and :MACRO is returned
> > as the first value.
>
> I'm not so sure that this is the right choice. Any code walker ought to have
> special knowledge about things that the standard explicitly says are special
> forms, even if they happen to be implemented as macros. I think it would be
> more useful to return :SPECIAL-FORM in such cases. I agree that :MACRO
> should be returned for things that are documented as being macros in the
> standard but that also have a special form implementation.
I thought about this but decided to go with a uniform approach, since if a code
walker has special knowledge about the thing then it is only going to care if
there is a local definition which shadows the global definition. Thus, if the
code walker has special knowledge about a name, it is going to treat the :MACRO
and :SPECIAL-FORM cases as synonymous, and meaning to go ahead and use its
special knowledge.
> > ENVIRONMENT-TYPE variable env [Function]
>
> Can we please call this function ENVIRONMENT-VARIABLE-TYPE again? To me,
> ENVIRONMENT-TYPE implies that it returns information about the kind of
> environment, not the type of variables in the environment.
>
> > ENVIRONMENT-FTYPE function env [Function]
>
> Perhaps ENVIRONMENT-FUNCTION-TYPE would be a better name?
Maybe. I definitely don't like the asymmetry of ENVIRONMENT-VARIABLE-TYPE and
ENVIRONMENT-FTYPE. Mine are shorter, though I agree with you about the
potential confusion for ENVIRONMENT-TYPE. Anybody else have an opinion?
> > AUGMENT-ENVIRONMENT env &KEY lexical
> > special
> > symbol-macro
> > function
> > macro
> > type
> > ftype [Function]
>
> Two problems here:
>
> - shouldn't there be a way to create a null environment object?
NIL is the :EVAL targeted null environment. Note that calling
AUGMENT-ENVIRONMENT with NIL as the environment and no keyword arguments can
legitimately return NIL. It is my current intention that WITH-COMPILATION-UNIT
with appropriate options will get you a :COMPILE or :COMPILE-FILE null
environment.
> - how does one specify the remoteness (or target) of the resulting
> environment?
It is inherited from the env argument.
> Is there any reason why the newly created environment object should -not-
> have indefinite extent? One of the alternatives suggested for issue
> MACRO-ENVIRONMENT-EXTENT was to allow &environment objects to have only
> dynamic extent within the macro function, but to provide some kind function
> to make copies that do have indefinite extent. Would calling
> AUGMENT-ENVIRONMENT with no keyword arguments do that?
There in fact are problems with specifying indefinite extent for environments,
as I mentioned in a recent message on MACRO-ENVIRONMENT-EXTENT.
AUGMENT-ENVIRONMENT with no keyword arguments will get you a copy, but the copy
should have the same extent as the source, ie. the extent of the
WITH-COMPILATION-UNIT form that created their ultimate ancestor.
> Also, I think it needs to be made more clear that the original environment is
> not destructively modified by this function.
True, since at least one reader missed that point.
> > ENVIRONMENT-PROPERTY env name property &optional default
> >
> > ...
>
> This doesn't make much sense to me -- you seem to be contradicting yourself
> about whether this attaches "global" or "local" properties to names. Perhaps
> you mean that if the environment is a "remote" environment, than the
> properties are local to that environment, but if it's a non-remote
> environment, then the properties are global?
The wording needs to be worked on. The intent is that if ENVIRONMENT-PROPERTY
is given a remote environment, it first examines the plist associated with that
environment. Failing to find the property there, it then looks at the
non-remote environment. The SETF method will modify the remote plist for a
remote environment, and the non-remote plist for a non-remote environment.
> I am uncomfortable about the idea of allowing environment objects to be
> destructively modified. Suppose I have an environment E1 and I pass it to an
> argument to AUGMENT-ENVIRONMENT to get environment E2. If I then modify the
> property list of E1, are the changes also reflected in E2?
Yes.
> I think this particular item needs more rationale to support it. I gather
> that this is supposed to be the internal mechanism by which CLOS hangs
> information about the class structure off the environment? Why does this need
> to be generalized -- what is wrong with having FIND-CLASS be the primitive
> accessor for this kind of information?
In a sense it is true that this function is not needed if we specify FIND-CLASS
(and all the other accessors and update functions that make a remote/non-remote
distinction. This function isn't just useful for CLOS. See recent message
regarding SYNTACTIC-ENVIRONMENT-ACCESS). However, without a function of this
sort it is much harder to write a PCL or similar portable program which needs
to record "global" information in the remote environment. For example, we
wrote a user extensible external type system (for an RPC) that makes use of
built-in and user-defined encoder and decoder methods. By straight-forward use
of our equivelent to ENVIRONMENT-PROPERTY, it was possible for the author of
this piece of code to make user-defined encoders and decoders accessable
downstream during a file compilation. No other hooks into the compiler were
needed.
An example of how it might be used is the following definition for something
like a Common Lisp MACRO-FUNCTION, where the expander is always kept on the
macro-expander property of the name.
(defun macro-function (name &optional env)
(multiple-value-bind (kind localp)
(environment-function-kind name env)
(when (eq kind :macro)
(if localp
<< do implementation-specific thing to find local macro >>
(environment-property env name 'macro-expander)))))
(defsetf macro-function (name &optional env) (expander)
`(setf (environment-property ,env ,name 'macro-expander) ,expander))
kab
-------
∂24-Feb-89 0158 CL-Compiler-mailer Symbols in compiled files, and Issues IN-PACKAGE-FUNCTIONALITY & CONSTANT-COMPILABLE-TYPES
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 24 Feb 89 01:58:18 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01290g; Fri, 24 Feb 89 01:51:49 PST
Received: by bhopal id AA19690g; Fri, 24 Feb 89 01:54:10 PST
Date: Fri, 24 Feb 89 01:54:10 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8902240954.AA19690@bhopal>
To: sandra%defun@cs.utah.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: CL-Compiler@SAIL.STANFORD.EDU,
sun!cperdue.Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
Subject: Symbols in compiled files, and Issues IN-PACKAGE-FUNCTIONALITY & CONSTANT-COMPILABLE-TYPES
I haven't forgotten about the following promise; but I will have to
postpone more details for another two weeks or so. Basically, I
don't believe we have anything to gain at this point in trying to
standardize the faslout package-qualification algorithm; this is
notwithstanding that standardizing PRINT output, as an interchange
format, is an absolute requirement [even though READ-of-PRINT will
likely be even more information losing than loading in a compiled file!]
-- JonL --
Date: Tue, 31 Jan 89 05:05:58 PST
From: Jon L White <jonl>
To: sandra%defun@cs.utah.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: CL-Compiler@SAIL.STANFORD.EDU,
Common-Lisp-Implementors@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Sandra J Loosemore's message of Wed, 25 Jan 89 09:58:52 MST <8901251658.AA20469@defun.utah.edu>
Subject: Issue: CONSTANT-COMPILABLE-TYPES (Version 5)
. . .
I intend to reply more fully to moon's "amendment" to your
IN-PACKAGE-FUNCTIONALITY proposal; and in that reply, I will detail
why it is the case that compiling out symbols should *not* be
specified to be any of the following three simple algorithms:
(1) fully-package qualified
(2) just like PRINT
(3) moon's minor variation on PRINT
That response will make it more clear why having two IN-PACKAGEs in a
single file ought to be allowable (although the Lucid documentation
warns against it for reasons of style). Anyone on this mailing list who
doesn't receive cl-cleanup mail, but who would like to see this reply,
should ask me privately for a copy. The essense of this reply will
be that it is useful for an implementation to allow as many gratuitous
variations in the package setup between compile-time and load-time
readings, provided that the source file does the same thing in each
variation.
. . .
∂24-Feb-89 0157 Common-Lisp-Object-System-mailer Issue CONSTANT-COMPILABLE-TYPES
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 24 Feb 89 01:57:23 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01286g; Fri, 24 Feb 89 01:43:50 PST
Received: by bhopal id AA19679g; Fri, 24 Feb 89 01:46:12 PST
Date: Fri, 24 Feb 89 01:46:12 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8902240946.AA19679@bhopal>
To: IIM%ECLA@ECLC.USC.EDU
Cc: sandra%defun@CS.UTAH.EDU, Moon@SCRC-STONY-BROOK.ARPA,
iim%ECLA@ECLC.USC.EDU, cl-cleanup@SAIL.STANFORD.EDU,
cl-compiler@SAIL.STANFORD.EDU,
common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett's message of Sun 19 Feb 89 15:48:59-PST <12472023082.5.IIM@ECLA.USC.EDU>
Subject: Issue CONSTANT-COMPILABLE-TYPES
re: ... only the programmers who define/use a class can
know how to properly copy, dump, test for equality (whatever equality
means), &etc. ... Removing structure objects from these kinds of
protocols and instead giving them trivial component-wise functionality
is utter nonsense. By all means we should give the programmer mechanisms
to help him specify that kind of behavior if that is what he wants. But
it must be a concious decision, not a default behavior! (As an aside, if
it were up to me, the default copier option for defstruct would be Nil.)
Kim, don't you have something turned around here? Previous mail
referred to CLtL p81 to show that defstruct instances should be
descended componentwise by EQUALP. This is not a statement about
classes in general -- just about structure-class, and its historic
meaning under EQUALP. Thus the Hawaii amendment was an *incompatible*
change (which has already raised some question in Lucid's customer land!).
This incompatible change unfortunately does nothing at all towards
supplying the "mechanisms" you call for, and in fact breaks some existing
code (in a very inscrutable way).
Given the failure to make EQUALP generic, wouldn't it be far better
to leave it alone and not make backwards-incompatible changes which
do no one any good?
-- JonL --
∂24-Feb-89 0754 Common-Lisp-Object-System-mailer Re: CLOS defining macros & compilation
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Feb 89 07:54:50 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA12042; Fri, 24 Feb 89 08:52:52 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA11101; Fri, 24 Feb 89 08:52:49 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902241552.AA11101@defun.utah.edu>
Date: Fri, 24 Feb 89 08:52:48 MST
Subject: Re: CLOS defining macros & compilation
To: Gregor.pa@Xerox.COM
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>,
cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
In-Reply-To: Gregor.pa@Xerox.COM, Thu, 23 Feb 89 20:23 PST
> Date: Thu, 23 Feb 89 20:23 PST
> From: Gregor.pa@Xerox.COM
>
> My belief is that resolution of this issue cannot proceed until the
> EVAL-WHEN issue has been resolved. I have been waiting to see what the
> resolution would be on the Symbolics EVAL-WHEN proposal. I haven't said
> anything about it before, but that proposal looks right to me. I
> believe it has what it would take to implement any of the CLOS behaviors
> I outlined to the CLOS group. I don't understand how to provide
> reasonable CLOS semantics with the previous propsal.
>
> Once the status of EVAL-WHEN is clear, and I get some more feedback
> about the message I sent, I will be able to rewrite the relevant part of
> Chapter 3. That rewrite will cover more than what we want to put in the
> standard just now, but it will make it clear exactly what the behavior
> should be. It will give us a precise model with which to decide exactly
> what how much to put in the standard. Then it should be easy to reduce
> it to what the compiler committee report should say.
I think you should go ahead and assume that the Symbolics EVAL-WHEN
proposal, or something very much like it, will be accepted. I believe
we are all pretty much in agreement with the goals Kent set out. I
may still put together an alternate proposal but the changes would be
more in the way it's presented than in the semantics.
Do you have any idea how long it will take you to do this revision to
Chapter 3? My understanding is that it will require truly exceptional
circumstances to get anything into the standard after the upcoming
meeting. We may need to do this all in parallel instead of series to
get things done in time.
Thanks for keeping us updated on this.
-Sandra
-------
∂24-Feb-89 0805 CL-Compiler-mailer re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Feb 89 08:05:41 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA12352; Fri, 24 Feb 89 09:03:40 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA11121; Fri, 24 Feb 89 09:03:37 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902241603.AA11121@defun.utah.edu>
Date: Fri, 24 Feb 89 09:03:35 MST
Subject: re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: Kim A. Barrett <IIM@ECLA.USC.EDU>
Cc: sandra%defun@cs.utah.edu, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett <IIM@ECLA.USC.EDU>, Thu 23 Feb 89 21:40:04-PST
Just for the record, here are the relevant bits of back mail I have
dealing with why we should consider only ENVIRONMENT-REMOTE-P instead
of specific targets for the environment. It seemed like we had pretty
much reached consensus on this before and I think it we have better things
to do with our time than hash this all out again.
From: sandra%defun@cs (Sandra J Loosemore)
Date: Mon, 3 Oct 88 10:56:21 MDT
> Date: Sun, 2 Oct 88 11:30:37 pdt
> From: Eric Benson <eb@lucid.com>
>
> ENVIRONMENT-TARGET env [Function]
>
> This function returns one of the three symbols EVAL, COMPILE or
> COMPILE-FILE, depending on whether the environment is from the
> interpreter, the in-core compiler, or the file compiler. If
> MACROEXPAND or MACROEXPAND-1 is called directly without supplying
> the environment argument, the environment passed to any expander
> functions will have target EVAL.
I really dislike this part of the proposal. I hate to have to keep
repeating myself, but there are other situations besides the three
listed here in which code may be processed. The example I've cited
before is a filter that reads in code from a file, performs some
preprocessing to decorate the code with lots of type declarations, and
writes it out to another file. I contend that anything that needs to
know whether the code is being processed by the interpreter or
compiler ought to be a special form (this includes EVAL-WHEN and
whatever we decide to do about LOAD-TIME-EVAL) and should be left
strictly alone by code walkers.
Date: Mon, 3 Oct 88 22:51 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
> ENVIRONMENT-TARGET env [Function]
>
> This function returns one of the three symbols EVAL, COMPILE or
> COMPILE-FILE, depending on whether the environment is from the
> interpreter, the in-core compiler, or the file compiler. If
> MACROEXPAND or MACROEXPAND-1 is called directly without supplying
> the environment argument, the environment passed to any expander
> functions will have target EVAL.
I really dislike this part of the proposal. I hate to have to keep
repeating myself, but there are other situations besides the three
listed here in which code may be processed. The example I've cited
before is a filter that reads in code from a file, performs some
preprocessing to decorate the code with lots of type declarations, and
writes it out to another file. I contend that anything that needs to
know whether the code is being processed by the interpreter or
compiler ought to be a special form (this includes EVAL-WHEN and
whatever we decide to do about LOAD-TIME-EVAL) and should be left
strictly alone by code walkers.
I think we have some confusion here between interpreter versus compiler
on the one hand, and operating in the local Lisp world versus outputting
to a file to be loaded later on the other hand. I feel that it is
completely inappropriate to add something that distinguishes between
the compiler and the interpreter. I'd like to see that part of the
proposal dropped.
The important distinction is between what I will call local environments
and remote environments. A defining form (DEFUN, DEFVAR, DEFCLASS, etc.)
evaluated in a local environment affects the current Lisp world, but in
a remote environment it does not affect the current Lisp world, however
its effects still need to be remembered in a model of the Lisp world
that will be created later. Both COMPILE-FILE and your example program
annotating program work with remote environments. I defy you to come up
with an example where the local/remote environment distinction doesn't
make sense and a third type is needed. Thus I think ENVIRONMENT-TARGET
would better be named ENVIRONMENT-REMOTE-P.
[...]
Again the compiler/interpreter distinction is a red herring and CLOS has
no reason to care about that distinction. The important distinction
is local/remote. CLOS needs to know whether a DEFCLASS form changes the
behavior of objects of that class in the current world, or only affects
a future ("remote") world. Whether this information is "inside" the
environment or "associated with" the environment is a red herring too,
I think; it's a matter of implementation, but has no effect on the
functional interface that the user sees. I think it's better only to
standardize the one thing that has to be standardized, the local/remote
distinction, and leave the rest (the actual name<->object mapping) to
the discretion of individual implementations. That way we'll get this
business over with quicker.
From: sandra%defun@cs (Sandra J Loosemore)
Date: Mon, 3 Oct 88 22:00:24 MDT
> Date: Mon, 3 Oct 88 22:51 EDT
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> The important distinction is between what I will call local environments
> and remote environments. A defining form (DEFUN, DEFVAR, DEFCLASS, etc.)
> evaluated in a local environment affects the current Lisp world, but in
> a remote environment it does not affect the current Lisp world, however
> its effects still need to be remembered in a model of the Lisp world
> that will be created later. Both COMPILE-FILE and your example program
> annotating program work with remote environments. I defy you to come up
> with an example where the local/remote environment distinction doesn't
> make sense and a third type is needed. Thus I think ENVIRONMENT-TARGET
> would better be named ENVIRONMENT-REMOTE-P.
That's a very nice way to put it. Rather than trying to introduce
*more* kinds of environments, I would actually go in the other
direction and say that code walkers shouldn't even need to know the
distinction between local and remote environments. An implementation
ought to be free to use different representations for the two, but as
long as the accessors return the correct information, is there any
reason why you would need to know where it came from?
> Again the compiler/interpreter distinction is a red herring and CLOS has
> no reason to care about that distinction. The important distinction
> is local/remote. CLOS needs to know whether a DEFCLASS form changes the
> behavior of objects of that class in the current world, or only affects
> a future ("remote") world.
That's pretty much what I was trying to say: CLOS doesn't really need
to know whether the information is needed by the compiler or
interpreter or something else, as long as it finds the right
information.
If the local/remote environment model is adopted (or even if we don't
provide any way to tell the difference between the two), some way
would have to be provided for a code walker to create a remote
environment. The existing proposal assumes that everything the
compiler doesn't create must be an EVAL (that is, local) environment.
Date: Wed, 5 Oct 88 18:58:37 CDT
From: David N Gray <Gray@DSG.csc.ti.com>
> ENVIRONMENT-TARGET env [Function]
>
> This function returns one of the three symbols EVAL, COMPILE or
> COMPILE-FILE, depending on whether the environment is from the
> interpreter, the in-core compiler, or the file compiler.
I agree with Moon's comments that the real issue is local versus remote.
-------
∂24-Feb-89 1005 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 24 Feb 89 10:05:02 PST
Received: by ti.com id AA13957; Fri, 24 Feb 89 12:03:35 CST
Received: from Kelvin by tilde id AA07514; Fri, 24 Feb 89 11:58:06 CST
Message-Id: <2813335075-11596439@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 24 Feb 89 11:57:55 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU, Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
In-Reply-To: Msg of Thu, 23 Feb 89 19:42 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> * Pursuant to the discussion I had with Moon prior to drafting version 5,
> one way to look at my model is simply:
>
> EVAL = COMPILE + LOAD
>
> Either the left side of the equation is run, or the right side.
I'm having trouble understanding what you are saying here.
> By unifying EVAL and LOAD as simply :EXECUTE in your revised list, you've
> destroy an important property of my keywords because you rob me of the
> ability to distinguish the `execute' which goes along with not-COMPILE case
> from the `execute' which goes along with the COMPILE case.
I wasn't intending my :EXECUTE to be different from your :EXECUTE. I'm
not sure if I just used a poor choice of words to describe it or if I've
missed some subtlety of your proposal.
> * As for :COMPILE-ALWAYS, an example might help. But I think you've isolated
> a potentially `real' point of disagreement on goal (vs solution, which we've
> been mostly discussing) when you say
>
> ``... This would be less common, but could still be useful for things
> like noticing that a definition of a function exists in order to
> suppress warnings about calls to an undefined function. ...''
>
> I very strongly believe not only that this should not be a goal, but
> that it should be a goal to prohibit the compiler from being allowed to
> take such action.
>
> If I have a function that is going to reliably define another function
> and the compiler doesn't notice it, what I want is a way to declare
> (i.e. proclaim) to the compiler that I promise to deliver that function
> in time. What I do -not- want is for the compiler to not warn me in the
> absence of such a declaration. It might be that I really didn't
> realize that the thing would never get executed -- the compiler does
> me no favors by failing to alert me to this potential problem in the
> absence of the aforementioned proclamation.
>
> If you think otherwise, then the problem is more serious than I was
> assuming because we don't even have the same abstract goals in mind.
This gets into the realm of style warnings, which is highly subjective.
It is unlikely that we would reach a consensus about the right way to do
this. I don't foresee an occasion to use this situation myself, but I
included it for the sake of completeness, so as to not prevent someone
from doing this if they wanted to.
> * As for :COMPILE-PERMANENT, I could not convince myself that it would not
> be invasive to proprietary models of CL. What if someone really implements
> a compiler such that COMPILE-FILE of a file that creates package FOO
> does not leave package FOO present. It's my impression that what KCL
> does amounts to this by running the file compiler in a separate
> environment, but I can imagine totally different implementations
> that achieve the same effect.
I don't feel real comfortable with this either, but I was trying to
resolve the ambiguity about where the side-effects of compile-time
evaluation are supposed to occur. Our implementation uses a heuristic
approach that does the reasonable thing most of the time, but there have
been complaints from customers who get unexpected results. For example,
it is not obvious that (EVAL-WHEN (COMPILE) (DEFMACRO ...)) installs the
macro in the global resident environment, while (EVAL-WHEN (EVAL COMPILE
LOAD) (DEFMACRO ...)) just puts it in the compile-time environment. It
seems like it would be better to provide a way for the programmer to
indicate what he wants, even if the implementation can't always comply
fully.
> If we adopt the v5 semantics of EVAL-WHEN, there can't be a presentation in
> the documentation of `primary reasons' and `secondary reasons.' All you can
> do is to present the semantics. Hopefully you suggest an intuition (such as
> I did at the start of this message) but that intuition should not hide the
> full semantics of the operation.
I think this is a case of the difference between conforming to the
specification versus being what the customer wanted.
> * Re: ``... controlling the time of execution is what EVAL-WHEN is
> supposed to be for, so it seems odd that it works in some cases
> but not others.''
>
> I think this should not really be seen as an oddity. It doesn't do the job
> of LOAD-TIME-VALUE. Does that seem odd to you? It used to seem odd to me,
> but I've changed my opinion. I think that the two primitives do very
> different things (yet they both control time of execution).
The fundamental difference here is that EVAL-WHEN is used to control
when side-effecting actions occur, while LOAD-TIME-VALUE is used to
produce a result value. Consequently, the contexts in which they are
useful are different.
∂24-Feb-89 1112 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Feb 89 11:11:59 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 545375; Fri 24-Feb-89 14:08:25 EST
Date: Fri, 24 Feb 89 14:08 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
To: Gray@DSG.csc.ti.com
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, CL-Compiler@SAIL.Stanford.EDU,
Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <2813335075-11596439@Kelvin>
Message-ID: <890224140801.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Only addressing part of your message for now...
Date: Fri, 24 Feb 89 11:57:55 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> EVAL = COMPILE + LOAD
> Either the left side of the equation is run, or the right side.
I'm having trouble understanding what you are saying here.
> By unifying EVAL and LOAD as simply :EXECUTE in your revised list, you've
> destroy an important property of my keywords because you rob me of the
> ability to distinguish the `execute' which goes along with not-COMPILE case
> from the `execute' which goes along with the COMPILE case.
I wasn't intending my :EXECUTE to be different from your :EXECUTE. I'm
not sure if I just used a poor choice of words to describe it or if I've
missed some subtlety of your proposal.
LOAD and COMPILE have meaning only when in a non-top-level position.
EVAL has meaning only in a top-level position.
For any given context, if LOAD is `being considered,' then COMPILE is
`being considered' -- and vice versa.
For any given context, if LOAD and COMPILE are `being considered' then
EVAL is not `being considered' -- and vice versa.
In terms of fractions, if we think in terms of dividing up the work between
several EVAL-WHEN's, then
(EVAL-WHEN (COMPILE) 50%-A)
(EVAL-WHEN (LOAD) 50%-A)
(EVAL-WHEN (EVAL) 100%-B)
expresses two different implementations of a problem. One for top-level, one
for embedded. Another common use is
(EVAL-WHEN (COMPILE) 0%-A)
(EVAL-WHEN (LOAD) 100%-A)
(EVAL-WHEN (EVAL) 100%-B)
or (EVAL-WHEN (EVAL LOAD) 100%-A/B)
or just A/B
Both of these (the 50-50-100 and the 0-100-100) support the formula
EVAL = LOAD + COMPILE. That is,
100% = 50% + 50%
100% = 100% + 0%
Now, we both know it may sometimes be the case that you have to write
100% = 60% + 60%
because it's harder to break up the work in two pieces. This really just
says something about the fact that the `+' isn't exactly the right operator.
I still think, though, that the true operator is one with much the same
behavior as plus, so I think it's adequate to abuse `+' this way for the
sake of a simple rule of thumb.
Also, nothing keeps you from doing only half the equation. eg, you may be
willing to write something which only works interpreted, or you may want to
put in an error check to see that something only gets compiled. The equation
in those cases ends up looking like
100% = 0% + 0%
or 0% = 100% + 100%
Now even our funny `+' operator can tell that this equation doesn't balance.
Obviously it doesn't mean that you're doing something illegal, but it is at
least a nice intuitive hint that you are doing something `clever' (and `clever'
in my book is a synonym for `questionable' whenever it is used in a programming
context).
The mere fact that our version of the proposal makes it possible to
distinguish `questionable' uses of EVAL-WHEN from `normal' uses is a virtue,
in my opinion.
Now, getting back to the original point that I replied to and that you were
confused by, if you eliminate EVAL and LOAD and you leave only EXECUTE in its
place, you get a confusing mess like
Embedded Top-Level
EXECUTE = EXECUTE + COMPILE
... or at least I do. And I don't see what good I'm going to be able to
derive from it. I also don't see how I'm going to be able to write code to
`complement' what the `COMPILE' phase does specially if I can't tell whether
or not the COMPILE phase has run. Note that the neat thing in our thing is
you can tell from within an (EVAL-WHEN (COMPILE) ...) that any accompanying
(EVAL-WHEN (LOAD) ...) has run and that any accompanying (EVAL-WHEN (EVAL) ...)
has not run just by virtue of knowing that you yourself are running.
∂24-Feb-89 1533 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Feb 89 15:29:58 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA00370; Fri, 24 Feb 89 16:28:02 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA11369; Fri, 24 Feb 89 16:27:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902242327.AA11369@defun.utah.edu>
Date: Fri, 24 Feb 89 16:27:57 MST
Subject: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: cl-compiler@sail.stanford.edu
Here is a draft of an alternate EVAL-WHEN proposal. Basically, what
I have done is to fix the problem with the IGNORE-COMPILE proposal
from version 4 that would have caused multiple evaluations in some
cases, and merge that with the new interpretation of the EVAL
situation from Kent's GENERALIZE-EVAL proposal from version 5.
Note that this proposal meets all of the same goals that were set out
in the version 5 writeup.
Since a number of people were getting hung up on the idea of EVAL-WHEN
not passing through top-level-ness, I have introduced another term,
"unshielded". Avoiding confusion is the only reason why I have not
made "unshielded" and "top-level" be the same (although I personally
think the writeup would be simpler if they were). Note that the
writeup for issue DEFINING-MACROS-NON-TOP-LEVEL would also have to be
changed to use "unshielded" instead of "top-level".
I am open to suggestions on this writeup. If everybody else hates
this and thinks that the the general direction here is totally wrong,
I will shut up and go along with the GENERALIZE-EVAL proposal. But I
personally would like to see something like this included in the
writeup we send out to X3J13 to vote on.
Proposal EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-FIX-NESTING:
Replace the description of EVAL-WHEN with the following:
EVAL-WHEN ({situation}*) {form}* [Special Form]
The body of an EVAL-WHEN form is processed as an implicit PROGN, but
only if the situations listed match the processing context. Each
SITUATION must be a symbol, either COMPILE, LOAD, or EVAL.
The context in which an EVAL-WHEN form is processed is referred to as
either shielded or unshielded. The EVAL situation controls processing
of the body in shielded contexts, and the COMPILE and LOAD situations
together control processing of the body in unshielded contexts.
Forms processed by COMPILE-FILE are considered to be shielded if
they appear at non-top-level or are enclosed within an EVAL-WHEN.
Forms that are processed by the COMPILE and EVAL functions are always
considered to be non-top-level and therefore shielded.
The behavior of EVAL-WHEN may be more precisely understood in terms
of a model of how the file compiler, COMPILE-FILE, processes forms
in a file to be compiled. Successive top-level forms are read from
the file using READ and examined by the file compiler before reading
the next.
* If the form is a macro call, it is expanded and the result is
examined recursively as a top-level form.
* If the form is a PROGN, each of its body forms are sequentially
examined as top-level forms.
* If the form is a COMPILER-LET, MACROLET, or SYMBOL-MACROLET, the file
compiler makes the appropriate bindings and the body forms are
recursively examined as an implicit top-level PROGN with those
bindings in effect.
* If the form is an EVAL-WHEN form and the context is unshielded, then
the file compiler performs two processing steps. First, if the
EVAL-WHEN form specifies the COMPILE situation, then the body of the
EVAL-WHEN is evaluated as an implicit PROGN in the executing
environment of the compiler. Then, if the LOAD situation is
specified, the body is recursively examined as an implicit top-level
PROGN, but in a shielded context.
* In all other cases, the compiler arranges for the form to be executed
when the compiled file is loaded. Any subforms are considered to be
non-top-level forms.
If an EVAL-WHEN form appears in a shielded context and the EVAL
situation is specified, then its body is processed as an implicit
PROGN. If the EVAL situation is not specified, the body is ignored
and the EVAL-WHEN form returns a value of NIL.
Clarifications/Consequences:
The following effects are logical consequences of the above proposal:
* It is never the case that the execution of a single EVAL-WHEN
expression will execute the body code more than once.
* The keyword `EVAL' is a misnomer because execution of
the body need not be done by EVAL. In compiled code, such as
(DEFUN FOO () (EVAL-WHEN (EVAL) (PRINT 'FOO)))
it is permissible (even desirable) for the call to PRINT to be compiled.
* Macros intended for use in top-level forms should arrange for all
side-effects to be done by the forms in the macro expansion.
The macro-expander itself should not do the side-effects.
* Placing a variable binding around an EVAL-WHEN reliably captures the
binding because non-top-level forms are always processed in a
shielded context.
* An outer EVAL-WHEN always shadows an inner EVAL-WHEN. The behavior
of nested EVAL-WHENs is symmetric for all three situations:
An EVAL-WHEN in a shielded context that specifies the EVAL situation
enables normal execution of its body. If the EVAL situation is not
specified, the normal execution of all body forms is prevented, even
nested EVAL-WHENs that do specify the EVAL situation.
An EVAL-WHEN in an unshielded context that specifies the LOAD
situation enables load-time execution of its body. If the LOAD
situation is not specified, the load-time execution of all body forms
is prevented, even nested EVAL-WHENs that do specify the LOAD
situation.
An EVAL-WHEN in an unshielded context that specifies the COMPILE
situation enables compile-time execution of its body. If the COMPILE
situation is not specified, the compile-time execution of all body
forms is prevented, even nested EVAL-WHENs that do specify the COMPILE
situation.
* One possible implementation of EVAL-WHEN is as a macro, assuming
some implementation-dependent way of determining whether an environment
is a top-level or non-top-level environment.
(defmacro eval-when (situations &body body &environment env)
(if (not (top-level-environment-p env))
(expand-shielded-eval-when situations body)
(progn
(if (member 'compile situations)
(mapcar #'eval body))
(if (member 'load situations)
`(macrolet ((eval-when (s &body b)
(expand-shielded-eval-when s b)))
,@body)
nil))
))
(defun expand-shielded-eval-when (situations body)
(if (member 'eval situations)
`(progn ,@body)
nil))
Test Cases:
;; #1: The EVAL-WHEN in this case is in a non-top-level position, so only
;; the EVAL keyword is considered. At compile time, this has no effect.
;; At normal execution time this sets (SYMBOL-FUNCTION 'FOO1) to a
;; function which returns 1.
(LET ((X 1))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO1) #'(LAMBDA () X))))
;; #2: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting
;; (SYMBOL-FUNCTION 'FOO2) to a function which returns 2.
(EVAL-WHEN (EVAL LOAD COMPILE)
(LET ((X 2))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO2) #'(LAMBDA () X)))))
;; #3: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting the
;; function cell of FOO3 to a function which returns 3.
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO3) #'(LAMBDA () 3)))
;; #4: This always does nothing. It simply returns NIL.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (COMPILE)
(PRINT 'FOO4)))
;; #5: If this form occurs at top-level of a file to be compiled, FOO5 is
;; printed at compile time. If this form occurs in a non-top-level
;; position, nothing is printed at compile time. Regardless of context,
;; nothing is ever printed at load time or execution time.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (EVAL)
(PRINT 'FOO5)))
;; #6: The description of EVAL-WHEN in CLtL says that this form will print
;; FOO6 at compile time. The description of EVAL-WHEN in this proposal
;; says it will never print anything.
(EVAL-WHEN (EVAL LOAD)
(EVAL-WHEN (COMPILE)
(PRINT 'FOO6)))
Rationale:
This behavior specified by this proposal is simple and easy to
understand, and extends the behavior of EVAL-WHEN usefully to
non-top-level situations. It is largely compatible with the behavior
of EVAL-WHEN specified in CLtL, except for the situation shown in
example #6 above. Some people find the nesting behavior of EVAL-WHEN
specified in this proposal to be an improvement over that specified
in CLtL.
This gives a useful meaning to EVAL-WHEN that supports useful and
predictable behavior if defining macros are used in a non-top-level
situation.
-------
∂27-Feb-89 0854 CL-Compiler-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 27 Feb 89 08:53:57 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA20033; Mon, 27 Feb 89 09:52:01 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00761; Mon, 27 Feb 89 09:51:58 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902271651.AA00761@defun.utah.edu>
Date: Mon, 27 Feb 89 09:51:57 MST
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY
To: cl-compiler@sail.stanford.edu
Cc: common-lisp-object-system@sail.stanford.edu
I have a new version of this proposal in the works. I've consulted
with Kathy Chapman on how to handle the wording problems that were
brought up earlier. But, there is still the paragraph that deals with
CLOS that some people indicated there were problems with.
This is the way it reads now:
(h) The compiler may assume that a class name defined by DEFCLASS
that is present in the compiletime environment will also be a
class name at runtime, and that class will be an instance of the
same metaclass. There may be additional conformance requirements
imposed by the metaclass, but there are none for STANDARD-CLASS.
Would anyone like to suggest some alternate wording?
A problem with the existing language that occurs to me is that the
previous paragraph of the proposal says that type specifiers
introduced with DEFTYPE or DEFCLASS must be defined the same at
runtime as at compiletime. The idea is that, if the compiler is
allowed to "wire in" type information (by making use of declarations,
for example), those types have to fit into the type hierarchy in the
same way at runtime as at compiletime. To me it seems like these same
considerations must also apply to types introduced by DEFCLASS,
regardless of the metaclass involved.
-Sandra
-------
∂27-Feb-89 0938 CL-Cleanup-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 27 Feb 89 09:37:15 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa07069; 27 Feb 89 17:20 GMT
Date: Mon, 27 Feb 89 17:23:28 GMT
Message-Id: <3256.8902271723@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Potential issue: MACRO-SPECIAL-FORMS
To: Kent M Pitman <KMP@scrc-stony-brook.arpa>
In-Reply-To: Kent M Pitman's message of Thu, 23 Feb 89 17:43 EST
Cc: cl-compiler@sail.stanford.edu, cl-cleanup@sail.stanford.edu
Kent --
Either you misunderstood what I said, or I failed to state it with
sufficient clarity. I was not trying to say that *all* implementation-
dependent functions in macro expansions (of constructs documented as
macros in CLtL) are bad, but rather that *certain kinds of functions*
are. So the CltL claim that "there is no problem" with functions is
wrong, and I was hoping that we might be able to rule out the bad
functions while keeping the good ones.
It was not my goal to eliminate calls to all functions that do "magic
things that no user could ever possibly hope to write", because, as
you point out, many "usually-seen-as-ordinary" functions have that
property. Rather, I wanted to deal with the possibility that an
implementation might satisfy the letter of the law but nonetheless, by
using functions and quoted arguments instead of out-and-out special
forms, still make it impossible for code-walkers and the like to
reliably find all the forms in an expression.
> Date: Thu, 23 Feb 89 22:00:42 GMT
> From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
> For example, a special form (sf . args) might expand to
> (do-an-sf '(sf . args)), where do-an-sf is an implementation
> -dependent function.
> A program-analyzing program learns nothing of value from such
> an expansion.
> This part is not true and weakens your earlier point (which I think is
> well-taken).
Well, consider my example with 'sf' instantiated to UNWIND-PROTECT
(which isn't defined as a macro and so isn't really a proper instance
of the problem), and 'args' to ((FOO) (BAR)). You write:
> For example, if UNWIND-PROTECT were not a standard special form but
> was added by some implementation with a macroexpander that turned
>
> (UNWIND-PROTECT (FOO) (BAR))
> into
> (SI::UNWIND-PROTECT-FUNCTION #'(LAMBDA () (FOO))
> #'(LAMBDA () (BAR)))
> this would be fine.
I agree that this is fine. But suppose it expanded (as in my example)
to:
(DO-AN-UNWIND-PROTECT
'(UNWIND-PROTECT (FOO) (BAR)))
That is not fine. I don't think anything in CLtL rules it out,
and I have seen things like it in at least one implementation.
> While you're right when you say I don't "learn" anything from
> examining the latter form, you're wrong when you fail to observe that
> I can `walk' the latter form reliably, while I cannot walk the former.
I meant "learn" to be interpreted rather loosely. The result is not
a useful one, because everything is hidden inside the QUOTE and so
would be ignored by a code-walker.
> For example, the implementation of Flavors used by Cloe uses a
> code-walker [...] What is important to that code walker (and a whole
> class of code walkers like it) is that it know what parts of something
> are `evaluated normally,' what parts are `evaluated specially,' and
> what parts are `not evaluated.'
I agree about what is important. I was trying to say something
similar in the "not quite a proposal":
The basic goal is that the intent of the macro definition should be
evident in the expansion. Subexpressions of the macro call that are
identified syntactically as forms should appear as forms in the
expansion, variables should appear as variables, and so on. But we
can't say they must appear only as forms, variables, and so on; so
it's not clear that the goal is an attainable one. There are
presumably other problems as well.
-- Jeff
∂28-Feb-89 1340 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 28 Feb 89 13:40:31 PST
Date: Tue 28 Feb 89 13:38:19-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12474358592.19.IIM@ECLA.USC.EDU>
> Date: Thu, 23 Feb 89 20:21:36 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> > The following functions provide information about syntactic environment
> > objects. In all of the functions the argument named ENV is a environment,
> > of the sort received by the &ENVIRONMENT argument to a macro, or as the
> > environment argument for EVALHOOK. In all cases it is an error to supply
> > an argument which is not a syntactic environment.
>
> Don't you want to permit passing NIL to signify the global, null lexical,
> environment?
Yeah. I keep forgetting to be more explicit about NIL.
> In fact, since the usefulness of many of these functions is not limited to
> local environments, instead of, for example,
>
> ENVIRONMENT-VARIABLE-KIND variable env [Function]
>
> it might be better to have:
>
> VARIABLE-KIND variable &optional env [Function]
I tried to avoid making major syntactic changes from version 1, so as to
proceed in smaller steps in case of a misstep. Also, I had been thinking about
these functions as being sort of accessors on environments, apparently mentally
reversing the arguments to these functions (ie. (fn-name env ...)). Now that
its been pointed out to me, I think I prefer your suggested syntax.
> I agree with Sandra's comments that ENVIRONMENT-REMOTE-P makes more sense,
Having now seen the arguments for this, I'm mostly inclined to agree. I do
have one reservation though, because I would like to have the ability to
differentiate between interpreted and compiled situations. If neither this nor
EVAL-WHEN gives me that capability, then I have a problem with the situation.
More on this in a seperate message.
> and that AUGMENT-ENVIRONMENT needs an argument to specify whether a remote
> environment is being created.
No, the intent is that AUGMENT-ENVIRONMENT returns an environment whose
remoteness is the same as the environment supplied as an argument. There is
nothing in this proposal which specifies how to create a new remote environment
out of nothingness. I want that pushed over to WITH-COMPILATION-UNIT, so that
we can talk about the extent of an environment in terms of the extent of the
creating form.
> Since the default type for variables is T, shouldn't the default for
> functions be FUNCTION instead of NIL?
This was a slip on my part. Yes.
> I would really like to see the proposal say that these two functions will
> return information that the user put in the environment with
> AUGMENT-ENVIRONMENT, but is not guaranteed to return anything other than the
> default types when given an environment received from the evaluator or
> compiler. I don't want the interpreter to have to go to the trouble of
> recording type declarations [that it doesn't use] just in case someone might
> ask to see them later.
I agree there is an argument that type declarations ought to be optional,
especially since the implementation is free to otherwise completely ignore
them. Since most uses of the type information are going to require using
SUBTYPEP, which could return `unknown', anybody using this information is
probably going to have to include reasonable default handling as well.
> Presumably it is also valid for MACROEXPAND, or is that included in what you
> mean by "syntactic analysis"?
Syntactic analysis means passing it to almost anything which takes an
environment argument, with the exception of EVALHOOK.
> It should be noted that only remote environments have property lists. In my
> implementation, the real difference between local and remote environments is
> whether storing into it affects the global environment or is recorded
> locally. In this proposal, (SETF (ENVIRONMENT-PROPERTY ...) ...) is the only
> way provided to store into an environment.
There is no intent to require property lists in the implementation, merely that
there exists this function which behaves as if there were property lists
underlying it. For example, the mechanism for handling local environments
might do case analysis on the name and property and invoke some specialized
code to deal with a particular case. For example, if the property is the
symbol MACRO-FUNCTION, and the name is a symbol, it might manipulate the
function cell of the symbol, while if name is a SETF function name it might go
to a special hash-table created for that purpose.
kab
*****
to sandra
-------
∂28-Feb-89 1344 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 28 Feb 89 13:43:24 PST
Date: Tue 28 Feb 89 13:39:26-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12474358795.19.IIM@ECLA.USC.EDU>
> I contend that anything that needs to know whether the code is being
> processed by the interpreter or compiler ought to be a special form (this
> includes EVAL-WHEN and whatever we decide to do about LOAD-TIME-EVAL) and
> should be left strictly alone by code walkers.
I don't agree with this. There are occasionally times when I (at least) want
to write a macro which does something different depending on whether it is
interpreted or compiled. In general they have the same meaning, the difference
often being in how much work the macro is willing to go to in order to produce
a 'good' expansion.
This is not to say that I disagree with the idea of replacing
ENVIRONMENT-TARGET with ENVIRONMENT-REMOTE-P. In fact, now that I've seen the
arguments, I agree thats the right thing.
The problem I have is that I may be left with no way to do what I want, because
we are removing the COMPILE bit from here, and the GENERALIZE-EVAL proposal for
EVAL-WHEN-NON-TOP-LEVEL seems to be removing it from EVAL-WHEN as well (which
is the other obvious mechanism for producing such a distinction).
kab
-------
∂28-Feb-89 1348 CL-Compiler-mailer remote environments
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 28 Feb 89 13:48:44 PST
Date: Tue 28 Feb 89 13:41:28-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: remote environments
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12474359164.19.IIM@ECLA.USC.EDU>
> Date: Thu, 23 Feb 89 18:38:01 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> DEFGENERIC
> The attributes of the generic function that affect DEFMETHOD will be
> recorded for use by definitions of methods for that generic function later
> in the file. This includes the lambda-list and method class. It is
> implementation-dependent whether this is actually put in the form of a
> generic function object and whether other operations on that generic
> function are possible at compile-time.
It may be desirable to require that the generic-function-class and the
method-class be instantiable, so that compile-time discrimination on those can
be done. Otherwise, there is a fair amount of generality specified in the MOP
which becomes pretty pointless.
kab
-------
∂28-Feb-89 1347 CL-Compiler-mailer Issue EVAL-WHEN-NON-TOP-LEVEL
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 28 Feb 89 13:47:19 PST
Date: Tue 28 Feb 89 13:40:44-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue EVAL-WHEN-NON-TOP-LEVEL
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12474359030.19.IIM@ECLA.USC.EDU>
> Date: Thu, 23 Feb 89 17:07:24 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> (1) It is not obvious why the body of the outer (EVAL-WHEN (COMPILE) ...)
> should not be considered to be top level.
To some extent I think this is really just an arbitrary decision. Most of the
different variations on whether EVAL-WHEN passes top-level that I've thought
about can be made to work. Its just a matter of what situations you then have
to include when writing your EVAL-WHENs so that they will work right, with some
choices on the pass-through producing requirements which are more intuitive
than others (though there is sometimes argument about which are more
intuitive).
> (2) The primary reason that person 1 used EVAL-WHEN was that they wanted it
> to happen at compile time; considerations of top-level-ness is a secondary
> detail. Person 2 also wants it to happen at compile time. So this appears
> to be a case of two rights make a wrong.
Consider the case of a DEFMACRO, which expands into an EVAL-WHEN COMPILE to
record the expander in the remote environment and a form which calls SETF of
MACRO-FUNCTION when the file is loaded. If you wrap an EVAL-WHEN COMPILE
around this, there is probably no point in recording the expander in the remote
environment, since it is about to be defined in the local environment.
kab
-------
∂28-Feb-89 1350 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 28 Feb 89 13:50:29 PST
Date: Tue 28 Feb 89 13:43:00-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: sandra%defun@CS.UTAH.EDU
cc: cl-compiler@SAIL.STANFORD.EDU, iim@ECLA.USC.EDU
Message-ID: <12474359444.19.IIM@ECLA.USC.EDU>
> From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Fri, 24 Feb 89 16:27:57 MST
>
> and merge that with the new interpretation of the EVAL situation from Kent's
> GENERALIZE-EVAL proposal from version 5.
But I don't want to see EVAL generalized in this way. I don't agree with the
following point
> * The keyword `EVAL' is a misnomer because execution of
> the body need not be done by EVAL. In compiled code, such as
> (DEFUN FOO () (EVAL-WHEN (EVAL) (PRINT 'FOO)))
> it is permissible (even desirable) for the call to PRINT to be compiled.
I think that if that got compiled then FOO should be a function of no arguments
which does nothing and returns NIL. I want a way to distinguish between
interpreted and compiled cases.
kab
-------
∂28-Feb-89 1429 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 28 Feb 89 14:28:54 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 547697; Tue 28-Feb-89 17:24:00 EST
Date: Tue, 28 Feb 89 17:23 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: IIM@ECLA.USC.EDU
cc: sandra%defun@CS.UTAH.EDU, cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: <12474359444.19.IIM@ECLA.USC.EDU>
Message-ID: <19890228222359.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Date: Tue 28 Feb 89 13:43:00-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
...
I think that if that got compiled then FOO should be a function of no arguments
which does nothing and returns NIL. I want a way to distinguish between
interpreted and compiled cases.
I take it to be a `given' that you should not have [portable]
primitives to distinguish between `interpreted' and `compiled'
cases, since there is no clear definition of what that means
in the presence of both interpreted-only and compiled-only
systems, and since (as a consequence) I think there is no reasonable
way for a portable program to make use of such knowledge.
On the other hand, I don't have an opposition to distinguishing
file-compiled from non-file compiled. The definition given by Moon and
me in v5 does so. Whether you have called COMPILE-FILE -is- something
that is invariant across implementations, and something which can be
simulated in an interpreted-only implementation (by making compile-file
just do macroexpansion) and which has real consequences which go beyond
implementation strategy (because of issues of `persistence of
environment', etc. -- the same issues that come up in the quote-equality
thing).
∂28-Feb-89 1555 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 28 Feb 89 15:55:00 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA07841; Tue, 28 Feb 89 16:53:03 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA01751; Tue, 28 Feb 89 16:52:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8902282352.AA01751@defun.utah.edu>
Date: Tue, 28 Feb 89 16:52:57 MST
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: Kim A. Barrett <IIM@ECLA.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett <IIM@ECLA.USC.EDU>, Tue 28 Feb 89 13:43:00-PST
After thinking about this for quite a while, I've come to believe that
Kent's interpretation of the EVAL situation is probably correct
because it makes sense in compiled-only implementations. Also, I did
a little investigation into current practice and found that both Lucid
and KCL treat the EVAL situation this way, so there is some precedent
for it.
-Sandra
-------
∂28-Feb-89 1635 CL-Compiler-mailer Re: remote environments
Received: from ti.com by SAIL.Stanford.EDU with TCP; 28 Feb 89 16:34:56 PST
Received: by ti.com id AA29607; Tue, 28 Feb 89 18:34:16 CST
Received: from Kelvin by tilde id AA18385; Tue, 28 Feb 89 18:30:45 CST
Message-Id: <2813704217-4830017@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Tue, 28 Feb 89 18:30:17 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "Kim A. Barrett" <IIM@ECLA.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU
Subject: Re: remote environments
In-Reply-To: Msg of Tue 28 Feb 89 13:41:28-PST from Kim A. Barrett <IIM@ECLA.USC.EDU>
> > DEFGENERIC
...
> It may be desirable to require that the generic-function-class and the
> method-class be instantiable, so that compile-time discrimination on those can
> be done. Otherwise, there is a fair amount of generality specified in the MOP
> which becomes pretty pointless.
Right. I was discussing the thing being defined, but was assuming that
any classes used in the definition would be instantiable. Its just a
question of whether that means that the programmer needs to use
(EVAL-WHEN (EVAL COMPILE LOAD) (DEFCLASS ...))
if the class is defined earlier in the same file.
∂28-Feb-89 1634 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ti.com by SAIL.Stanford.EDU with TCP; 28 Feb 89 16:34:36 PST
Received: by ti.com id AA29590; Tue, 28 Feb 89 18:33:55 CST
Received: from Kelvin by tilde id AA18193; Tue, 28 Feb 89 18:17:44 CST
Message-Id: <2813703430-4782723@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Tue, 28 Feb 89 18:17:10 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "Kim A. Barrett" <IIM@ECLA.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU
Subject: Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
In-Reply-To: Msg of Tue 28 Feb 89 13:38:19-PST from Kim A. Barrett <IIM@ECLA.USC.EDU>
> > It should be noted that only remote environments have property lists. In my
> > implementation, the real difference between local and remote environments is
> > whether storing into it affects the global environment or is recorded
> > locally. In this proposal, (SETF (ENVIRONMENT-PROPERTY ...) ...) is the only
> > way provided to store into an environment.
>
> There is no intent to require property lists in the implementation, merely that
> there exists this function which behaves as if there were property lists
> underlying it.
Right; I was intending "property list" in the conceptual sense, rather
than as an implementation representation. The point is that
(SETF (ENVIRONMENT-PROPERTY ...) ...) has a global side-effect if the
environment is not a remote environment.
∂28-Feb-89 1704 CL-Compiler-mailer Re: Issue EVAL-WHEN-NON-TOP-LEVEL
Received: from ti.com by SAIL.Stanford.EDU with TCP; 28 Feb 89 17:04:32 PST
Received: by ti.com id AA29728; Tue, 28 Feb 89 19:03:51 CST
Received: from Kelvin by tilde id AA18690; Tue, 28 Feb 89 18:48:27 CST
Message-Id: <2813705279-4893831@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Tue, 28 Feb 89 18:47:59 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "Kim A. Barrett" <IIM@ECLA.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU
Subject: Re: Issue EVAL-WHEN-NON-TOP-LEVEL
In-Reply-To: Msg of Tue 28 Feb 89 13:40:44-PST from Kim A. Barrett <IIM@ECLA.USC.EDU>
> > (2) The primary reason that person 1 used EVAL-WHEN was that they wanted it
> > to happen at compile time; considerations of top-level-ness is a secondary
> > detail. Person 2 also wants it to happen at compile time. So this appears
> > to be a case of two rights make a wrong.
>
> Consider the case of a DEFMACRO, which expands into an EVAL-WHEN COMPILE to
> record the expander in the remote environment and a form which calls SETF of
> MACRO-FUNCTION when the file is loaded. If you wrap an EVAL-WHEN COMPILE
> around this, there is probably no point in recording the expander in the remote
> environment, since it is about to be defined in the local environment.
Ah, good point. Now I understand why top-level-ness is relevant.
I think this discussion illustrates how confusingly vague the meaning of
the current COMPILE situation is. If we replaced it with situations
such as :COMPILE-TOP-LEVEL and :COMPILE-ALWAYS, then it would become
much more obvious what is happening and why. I guess the intent was to
define COMPILE to mean compile-time-if-top-level, but if I'm still
confused by it, then other programmers probably will be too.
∂01-Mar-89 1030 CL-Compiler-mailer Re: Issue WITH-COMPILATION-UNIT
Received: from ti.com by SAIL.Stanford.EDU with TCP; 1 Mar 89 10:30:34 PST
Received: by ti.com id AA02957; Wed, 1 Mar 89 12:18:04 CST
Received: from Kelvin by tilde id AA06738; Wed, 1 Mar 89 12:13:45 CST
Message-Id: <2813767988-8661469@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Wed, 1 Mar 89 12:13:08 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "Kim A. Barrett" <IIM%ECLA@ECLC.USC.EDU>
Cc: kmp@SCRC-STONY-BROOK.ARPA, cl-compiler@SAIL.STANFORD.EDU
Subject: Re: Issue WITH-COMPILATION-UNIT
In-Reply-To: Msg of Sat 18 Feb 89 19:17:10-PST from Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
> What I'd like is to make the syntax of the macro be something like
>
> WITH-COMPILATION-UNIT var &body body
>
> and add something like the following to it description
>
> The body is processed with var bound to a compile-time environment. The
> extent of the environment is the dynamic extent of the form. This extent also
> applies to any environments made from it (directly or indirectly) by
> AUGMENT-ENVIRONMENT (see Issue SEMANTIC-ENVIRONMENT-ACCESS).
This is an interesting idea, but I am afraid it is mixing two things
that don't necessarily go together. In the Lisp Machine's MAKE-SYSTEM,
the environment for compile-time definitions is for each individual
file, while the warnings context includes all of the files.
> COMPILE-FILE needs a :environment argument.
Yes, if we have AUGMENT-ENVIRONMENT, then users might want to be able to
compile within an environment of macro definitions that they
constructed. It should be easy to permit this, although it might not be
so easy to specify the limitations on how to use it properly.
∂02-Mar-89 1037 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 10
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 2 Mar 89 10:37:42 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA04847; Thu, 2 Mar 89 11:23:49 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA03273; Thu, 2 Mar 89 11:23:35 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903021823.AA03273@defun.utah.edu>
Date: Thu, 2 Mar 89 11:23:33 MST
Subject: issue LOAD-TIME-EVAL, version 10
To: cl-compiler@sail.stanford.edu
Cc: moon@stony-brook.scrc.symbolics.com
Here is the writeup on this issue that incorporates the language
suggested by Moon. I've made that into an alternate proposal, and the
writeup includes both the new proposal and the one that was voted on
at the last meeting.
Forum: Compiler
Issue: LOAD-TIME-EVAL
References: #, (p. 356), (EVAL-WHEN (LOAD) ...) (p. 69-70)
issue SHARP-COMMA-CONFUSION
Category: ADDITION
Edit history: 06-Jun-87, Version 1 by James Kempf
17-Jul-87, Version 2 by James Kempf
12-Nov-87, Version 3 by Pitman (alternate direction)
01-Feb-88, Version 4 by Moon
(from version 2 w/ edits suggested by Masinter)
06-Jun-88, Version 5 by Pitman
(fairly major overhaul, merging versions 3 and 4)
21-Sep-88, Version 6 by Moon (stripped down)
17-Oct-88, Version 7 by Loosemore (change direction again)
30-Dec-88, Version 8 by Loosemore (tweaks)
23-Jan-89, Version 9 by Loosemore (amendments)
02-Mar-89, Version 10 by Loosemore (new proposal)
Problem description:
Common Lisp provides reader syntax (#,) which allows the programmer
to designate that a particular expression within a program is to be
evaluated early (at load time) but to later be treated as a constant.
Unfortunately, no access to this capability is available to programs
which construct other programs without going through the reader.
Some computations can be deferred until load time by use of EVAL-WHEN,
but since EVAL-WHEN must occur only at toplevel, and since the nesting
behavior of EVAL-WHEN is quite unintuitive, EVAL-WHEN is not a general
solution to the problem of load-time computation of program constants.
Proposal R**2-NEW-SPECIAL-FORM was approved at the January 1989
meeting. After the meeting, some additional suggestions were made that
have been incorporated into proposal R**3-NEW-SPECIAL-FORM.
Proposal (LOAD-TIME-EVAL:R**2-NEW-SPECIAL-FORM):
Add a new special form, LOAD-TIME-VALUE, which has the following
contract:
LOAD-TIME-VALUE form &optional read-only-p [Special Form]
LOAD-TIME-VALUE provides a mechanism for delaying evaluation of <form>
until the expression is in the "runtime" environment.
If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
performs normal semantic processing such as macro expansion but
arranges for the evaluation of <form> to occur at load time in a null
lexical environment, with the result of this evaluation then being
treated as an immediate quantity at run time. It is guaranteed that
the evaluation of <form> will take place only once when the file is
loaded, but the order of evaluation with respect to the "evaluation"
of top-level forms in the file is unspecified.
If a LOAD-TIME-VALUE expression appears within a function compiled
with COMPILE, the <form> is evaluated at compile time in a null lexical
environment. The result of this compile-time evaluation is treated as
an immediate quantity in the compiled code.
In interpreted code, <form> is evaluated (by EVAL) in a null
lexical environment, and one value is returned. Implementations which
implicitly compile (or partially compile) expressions passed to
EVAL may evaluate the <form> only once, at the time this
compilation is performed. This is intentionally similar to the
freedom which implementations are given for the time of expanding
macros in interpreted code.
Note that, in interpreted code, there is no guarantee as to when
evaluation of <form> will take place, or the number of times the
evaluation will be performed. Since successive evaluations of the
same LOAD-TIME-VALUE expression may or may not result in an evaluation
which returns a "fresh" object, destructive side-effects to the
resulting object may or may not persist from one evaluation to the
next. It is safest to explicitly initialize the object returned by
LOAD-TIME-VALUE, if it is later modified destructively.
Implementations must guarantee that each reference to a
LOAD-TIME-VALUE expression results in at least one evaluation of its
nested <form>. For example,
(DEFMACRO CONS-SELF (X)
`(CONS ,X ,X))
(CONS-SELF (LOAD-TIME-VALUE (COMPUTE-IT)))
must perform two calls to COMPUTE-IT; although there is only one
unique LOAD-TIME-VALUE expression, there are two distinct references
to it.
In the case of a LOAD-TIME-VALUE form appearing in a quoted expression
passed to EVAL, each call to EVAL must result in a new evaluation of
<form>. For example,
(DEFVAR X 0)
(DEFUN FOO () (EVAL '(LOAD-TIME-VALUE (INCF X))))
is guaranteed to increment X each time FOO is called, while
(DEFUN FOO () (LOAD-TIME-VALUE (INCF X)))
may cause X to be evaluated only once.
The READ-ONLY-P argument designates whether the result can be considered
read-only constant. If NIL (the default), the result must be considered
ordinary, modifiable data. If T, the result is a read-only quantity
which may, as appropriate, be copied into read-only space and/or shared
with other programs. (Because this is a special form, this argument is
-not- evaluated and only the literal symbols T and NIL are permitted.)
Rationale:
LOAD-TIME-VALUE is a special form rather than a function or macro
because it requires special handling by the compiler.
Requiring the compiler to perform semantic processing such as macro
expansion on the nested <form>, rather than delaying all such processing
until load time, has the advantages that fewer macro libraries may need
to be available at load time, and that loading may be faster and result
in less consing due to macroexpansion. If users really want to delay
macroexpansion to load time, this can be done with an explicit call to
EVAL, e.g.
(LOAD-TIME-VALUE (EVAL '(MY-MACRO)))
Allowing the same LOAD-TIME-VALUE to cause its nested <form> to be
evaluated more than once makes simplifies its implementation in
interpreters which do not perform a preprocessing code walk. It also
makes the rules for the time of its processing analogous to those
for macro expansion.
This proposal explicitly does -not- tie LOAD-TIME-VALUE to the #,
read macro. Doing so would be an incompatible change to the definition
of #, (which is reliably useful only -inside- quoted structure,
while LOAD-TIME-VALUE must appear -outside- quoted structure in a
for-evaluation position).
The requirement that LOAD-TIME-VALUE expressions be evaluated once per
reference (rather than once per unique expression) prevents problems
that could result by performing destructive side-effects on a value
that is unexpectedly referenced in more than one place.
Proposal (LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM):
Add a new special form, LOAD-TIME-VALUE, which has the following
contract:
LOAD-TIME-VALUE form &optional read-only-p [Special Form]
LOAD-TIME-VALUE provides a mechanism for delaying evaluation of <form>
until the expression is in the "runtime" environment.
If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
performs normal semantic processing such as macro expansion but
arranges for the evaluation of <form> to occur at load time in a null
lexical environment, with the result of this evaluation then being
treated as an immediate quantity at run time. It is guaranteed that
the evaluation of <form> will take place only once when the file is
loaded, but the order of evaluation with respect to the "evaluation"
of top-level forms in the file is unspecified.
If a LOAD-TIME-VALUE expression appears within a function compiled
with COMPILE, the <form> is evaluated at compile time in a null lexical
environment. The result of this compile-time evaluation is treated as
an immediate quantity in the compiled code.
In interpreted code, <form> is evaluated (by EVAL) in a null
lexical environment, and one value is returned. Implementations which
implicitly compile (or partially compile) expressions passed to
EVAL may evaluate the <form> only once, at the time this
compilation is performed. This is intentionally similar to the
freedom which implementations are given for the time of expanding
macros in interpreted code.
If the same (compared with EQ) list (LOAD-TIME-VALUE <form>) is
evaluated or compiled more than once, it is unspecified whether <form>
is evaluated only once or is evaluated more than once. This can
happen both when an expression being evaluated or compiled shares
substructure, and when the same expression is passed to EVAL or to
COMPILE multiple times. Since a LOAD-TIME-VALUE expression may be
referenced in more than one place and may be evaluated multiple times
by the interpreter, it is unspecified whether each execution returns
a "fresh" object or returns the same object as some other execution.
Users must use caution when destructively modifying the resulting
object.
If two lists (LOAD-TIME-VALUE <form>) are EQUAL but not EQ, their
values always come from distinct evaluations of <form>. Coalescing
of these forms is not permitted.
The READ-ONLY-P argument designates whether the result can be considered
read-only constant. If NIL (the default), the result must be considered
ordinary, modifiable data. If T, the result is a read-only quantity
which may, as appropriate, be copied into read-only space and/or shared
with other programs. (Because this is a special form, this argument is
-not- evaluated and only the literal symbols T and NIL are permitted.)
Rationale:
LOAD-TIME-VALUE is a special form rather than a function or macro
because it requires special handling by the compiler.
Requiring the compiler to perform semantic processing such as macro
expansion on the nested <form>, rather than delaying all such processing
until load time, has the advantages that fewer macro libraries may need
to be available at load time, and that loading may be faster and result
in less consing due to macroexpansion. If users really want to delay
macroexpansion to load time, this can be done with an explicit call to
EVAL, e.g.
(LOAD-TIME-VALUE (EVAL '(MY-MACRO)))
Allowing the same LOAD-TIME-VALUE to cause its nested <form> to be
evaluated more than once makes simplifies its implementation in
interpreters which do not perform a preprocessing code walk. It also
makes the rules for the time of its processing analogous to those
for macro expansion.
This proposal explicitly does -not- tie LOAD-TIME-VALUE to the #,
read macro. Doing so would be an incompatible change to the definition
of #, (which is reliably useful only -inside- quoted structure,
while LOAD-TIME-VALUE must appear -outside- quoted structure in a
for-evaluation position).
Allowing multiple references to the same LOAD-TIME-VALUE expression
to result in only one interpretation allows it to be specified more
cleanly. It also allows interpreters that do not perform a prepass
to cache LOAD-TIME-VALUE expressions.
Current Practice:
This is an addition to the language and has not yet been implemented.
Cost to Implementors:
In compiled code, (LOAD-TIME-VALUE <form>) is similar to
'#,<form>. Most implementations can probably make use of the same
mechanism they use to handle #, to handle LOAD-TIME-VALUE. Note that
#, does not currently provide a mechanism for dealing with
non-read-only-ness.
Implementing LOAD-TIME-VALUE in the interpreter should be fairly
straightforward, since one simply needs to evaluate the <form> in the
null lexical environment. Implementations that use a preprocessing
code walk in the interpreter to perform macro expansion could process
LOAD-TIME-VALUE forms at that time.
Some code-walkers would have to be taught about this new
special form. Such changes would likely be trivial.
Cost to Users:
Some code-walkers would have to be taught about this new
special form. Such changes would likely be trivial.
Benefits:
Users are given a mechanism that to force evaluation to be delayed
until load time that does not rely on a feature of the reader.
Discussion:
Earlier versions (up to version 7) of this proposal stated that
all semantic processing of the LOAD-TIME-VALUE form should be postponed
until load time.
The semantics of LOAD-TIME-VALUE would be simplified considerably if
the READ-ONLY-P argument were removed and destructive operations on
the result of evaluating <form> prohibited. However, some people feel
that the ability to destructively modify the value is an essential
feature to include.
"Collapsing" of multiple references to the same LOAD-TIME-VALUE
expression could be allowed for read-only situations, but it seems
like it would be more confusing to make it legal in some situations
and not in others.
A number of other alternatives have been considered on this issue,
including:
- A proposal for a new special form that would force evaluation of
the <form> to happen only once. This was rejected because of
implementation difficulties.
- A proposal to add a function making the "magic cookie" used by #,
available to user code. The current proposal does not prevent such
a function from being added, but this approach appeared to have
less support than making the hook available as a new special form.
- A proposal to remove #, entirely (issue SHARP-COMMA-CONFUSION).
- A suggestion to change the behavior of (EVAL-WHEN (LOAD) ...).
Kent Pitman says:
Although I'm willing to take multiple evaluation in the interpreter
as a compromise position, I would like it mentioned in the discussion
that this was only an expedient to getting this issue accepted at all,
and that I'm not really happy about it. I have said that I think a
number of our lingering problems (with EVAL-WHEN, COMPILER-LET, and
this -- for example) are due to the presence of interpreters which do
not do a semantic-prepass at a known time. If I had my way, we would
require a semantic pre-pass and we would then be able to forbid
multiple evaluations even in the interpreter.
Moon and Gray support proposal R**3-NEW-SPECIAL-FORM.
Pitman also expressed willingness to go along with
R**3-NEW-SPECIAL-FORM, but was somewhat concerned that coalescing
LOAD-TIME-VALUE results based on EQ-ness of the LOAD-TIME-VALUE form
could conceivably lead to trouble down the line. However, since he
could provide no actual examples to back up that worry, and since the
majority opinion was that some implementations would find a
restriction against such coalescing an undue burden, the decision was
made to just `note the concern' and proceed on. Sandra Loosemore and
JonL White concur with this position.
-------
∂03-Mar-89 0841 CL-Compiler-mailer Re: Issue LOAD-TIME-EVAL (shouldn't this be called issue
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 3 Mar 89 08:40:53 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa00173; 3 Mar 89 8:46 EST
Received: from draper.com by RELAY.CS.NET id aa03622; 3 Mar 89 8:41 EST
Date: Fri, 3 Mar 89 07:47 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Re: Issue LOAD-TIME-EVAL (shouldn't this be called issue
LOAD-TIME-VALUE?)
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER,SEB1525
> Some computations can be deferred until load time by use of EVAL-WHEN,
> but since EVAL-WHEN must occur only at toplevel, and since the nesting
> behavior of EVAL-WHEN is quite unintuitive, EVAL-WHEN is not a general
> solution to the problem of load-time computation of program constants.
"must occur only at toplevel"? That isn't true, is it? (In any case,
whether the nesting behavior of EVAL-WHEN is unintuitive may be resolved
by the outcome of the EVAL-WHEN-NON-TOP-LEVEL issue - then again, it may
be unintuitive no matter what is decided. :-) )
> If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
> performs normal semantic processing such as macro expansion but
"Normal semantic processing" includes transformation into machine code or
whatever the compiler normally does with code, right? This should be made
clearer, lest it be assumed that only macroexpansion is permitted.
∂05-Mar-89 1604 CL-Compiler-mailer deadlines
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 5 Mar 89 16:04:38 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA01383; Sun, 5 Mar 89 17:02:30 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05604; Sun, 5 Mar 89 10:54:30 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903051754.AA05604@defun.utah.edu>
Date: Sun, 5 Mar 89 10:54:29 MST
Subject: deadlines
To: cl-compiler@sail.stanford.edu
If you have comments or suggestions on -any- of the pending
cl-compiler issues, please get them to me by this coming Friday (the
10th). These things need to be sent out to X3J13 early next week to
meet the 2-week deadline, and this will give me a couple of days to
make a final pass over the writeups.
I expect that on a few of the issues we may need to do one more
iteration between next week and the meeting, particularly if we get a
lot of suggestions back from the wider community.
-Sandra
-------
∂05-Mar-89 1653 CL-Compiler-mailer subcommittee meeting
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 5 Mar 89 16:53:07 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA02196; Sun, 5 Mar 89 17:50:46 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05731; Sun, 5 Mar 89 17:50:44 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903060050.AA05731@defun.utah.edu>
Date: Sun, 5 Mar 89 17:50:42 MST
Subject: subcommittee meeting
To: cl-compiler@sail.stanford.edu
Cc: cperdue@sun.com
> Date: Sun, 5 Mar 89 14:13:08 PST
> From: cperdue@Sun.COM (Cris Perdue)
>
> Do you plan to hold a compiler subcommittee meeting on Monday
> March 27? If so, what time?
I wasn't planning to have a subcommittee meeting this time, because it
seemed like many people indicated they would not be able to make a
Monday meeting anyway. I will, however, be available Monday evening,
if anybody has something they want to discuss informally. Would people
be interested in getting together for dinner, say around 6ish?
We are tentatively on the agenda for Wednesday afternoon, BTW.
-Sandra
-------
∂05-Mar-89 1742 CL-Compiler-mailer issue CONSTANT-COMPILABLE-TYPES, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 5 Mar 89 17:42:10 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA02978; Sun, 5 Mar 89 18:40:07 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05764; Sun, 5 Mar 89 18:40:04 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903060140.AA05764@defun.utah.edu>
Date: Sun, 5 Mar 89 18:40:02 MST
Subject: issue CONSTANT-COMPILABLE-TYPES, version 7
To: cl-compiler@sail.stanford.edu
Thanks to Cris Perdue, here is a brand new version of this issue.
There have been a few major changes in content since the version that
was distributed prior to the January meeting:
- All mention of cross-compilation has gone away.
- The behavior of readtables, methods, and generic functions is now
unspecified. Functions are still in, but see the note I added to the
discussion section.
- Error terminology has changed. The proposal used to say "is an error"
but now requires implementations either to do something useful or
signal an error. If anybody has a problem with this, speak up.
Forum: Compiler
Issue: CONSTANT-COMPILABLE-TYPES
References: CLtL pp. 56, 77-80, 324
Issue CONSTANT-MODIFICATION
Issue CONSTANT-CIRCULAR-COMPILATION
Issue CONSTANT-ARRAY-ATTRIBUTES
Issue QUOTE-SEMANTICS
Issue LOAD-OBJECTS
Category: CLARIFICATION, ADDITION
Edit history: 11/07/88, V1 by Cris Perdue
11/14/88, V2 by Cris Perdue
11/22/88, V3 by Cris Perdue
12/20/88, V4 by Cris Perdue
01/06/89, V5 by Sandra Loosemore (minor editorial
clarifications, expand discussion)
03/05/89, V6 by Cris Perdue (more response to comments,
especially from Moon and and from Loosemore)
03/05/89, V7 by Loosemore (more editorial tweaks)
Status: Ready for release
Problem description:
CLtL does not specify what objects can be in compiled constants and it
does not say what relationship there is to be between the
constant passed to the compiler and the one that is established by
compiling and then loading its file. Relevant remarks in CLtL
concerning file compilation and the definition of QUOTE suggest that
the compiler handles constants in ways that are not actually possible.
Introduction to the proposal:
The proposal CONSTANT-COMPILABLE-TYPES:SPECIFY attempts to spell out
what types can appear in compiled constants, and what it means when
they appear. Unless stated otherwise, in this proposal where the term
"constant" is used, it means a quoted or self-evaluating constant, not
a named (defconstant) constant.
The key is a definition of a form of equivalence between Lisp objects,
"similarity as constants". Code passed through the file compiler and
then loaded must behave as though quoted constants in it are "similar"
to quoted constants in the corresponding interpreted "source" code.
Because it is legitimate to compile in one address space and load into
a different one, it is necessary for the constraints to be defined
across address spaces. This proposal only concerns quoted constants
to be processed by COMPILE-FILE. Some other issues related to file
compilation are CONSTANT-COLLAPSING, CONSTANT-CIRCULAR-COMPILATION,
and QUOTE-SEMANTICS.
Some implementations "lose information" about some constants during
compilation. Typically all constant arrays become simple arrays
during the process of compiling and loading. We try to balance the
desire for more functionality against the effort required from
implementors.
Comments within the text of the proposal are enclosed in double angle
brackets, <<like this>>.
Proposal: CONSTANT-COMPILABLE-TYPES:SPECIFY
An object may be used as a quoted constant processed by COMPILE-FILE
if the compiler can guarantee that the resulting constant established
by loading the compiled file is "similar as a constant" to the
original. Treatment of uninterned symbols must be consistent across
the entire file as described below. There also is a constraint on
arrays which is not symmetrical; compilation can make arrays
"simpler", but not "less simple". (See below for the definition.)
We refer below to "quoted constants" or just "constants". In this
section these terms refer to objects appearing in expressions of the
form (QUOTE <object>), to objects used as self-evaluating forms, and
to objects appearing in code at locations described as "not
evaluated".
Some types such as streams are not supported in constants. Put
another way, an object containing one of these is not considered
similar as a constant to any other object. Some implementations may
support them and define how they are treated. For any object that
appears in a constant, but is not supported by the language as part of
a constant, the behavior of the compiler is unspecified; either the
the compiler and/or loader will handle that constant (in an
implementation-dependent manner) or the compiler will detect the
situation and signal an error.
Of the types supported in constants, some are treated as aggregate
objects. For these types, being similar as constants is defined
recursively. We say that an object of these types has certain
attributes, and to be similar as a constant to another object, the
values of the corresponding attributes of the two objects must also be
similar as constants.
This kind of definition has problems with any circular or "infinitely
recursive" object such as a list that is an element of itself. We
use the idea of depth-limited comparison, and say that two
objects are similar as constants if they are similar at all finite
levels. This idea is implicit in the definitions below, and applies
in all the places where attributes of two objects are required to be
similar as constants.
Here we define the notion of two objects being "similar as constants",
organizing the definition by type, and note additional constraints
that the compiler and loader working together must meet:
Number
If either of the two objects is a number, both must be of the same
type and must represent the same mathematical value.
Character
If either of the two objects is a character, both must be character
objects that represent the same character. <<Note that this
definition has to depend on the results of the Character Set
proposals.>>
Random-state
Let us say that two random-states are functionally equivalent if
applying RANDOM to them repeatedly always produces the same
pseudo-random numbers in the same order.
Two random-states are similar as constants exactly if copies of them
made via MAKE-RANDOM-STATE are functionally equivalent.
Note that a constant random-state object cannot be used as the "state"
argument to the function RANDOM (because RANDOM side-effects this
data structure).
Symbol
A symbol can only be similar to a symbol. References to interned
symbols are "by name". <<See issue COMPILE-FILE-SYMBOL-HANDLING for
details.>>
If a symbol is not interned, i.e. its home package is NIL, it is
treated in a rather special way. To be similar as a constant to
another symbol, both symbols must be uninterned and have the same
name.
Constants that contain uninterned symbols have to satisfy an extra
constraint. Consider the set of places in a constant that refer to
the same (EQ) uninterned symbol. In any similar constant, the
corresponding places must also all be EQ -- no more places and no
fewer. Moreover, COMPILE-FILE must arrange for the EQness of all
constant uninterned symbols that appear in the file to be preserved,
even if they are referenced in separate constants.
Because hash keys can be aggregate objects and because we treat hash
tables as unordered sets of <key, value> pairs, similarity of hash
tables is more complex. See under "Hash Tables", below, for the
definition.
Package
A package can only be similar as a constant to a package. References
to packages are permitted in any constant. References to packages are
"by name": two packages are similar as constants when their names are
similar as constants. Within a Lisp "address space", packages with
the same name are EQ.
At load time, the package becomes the same as returned by
FIND-PACKAGE, given the package name. An error is signalled if no
package of that name exists at load time.
AGGREGATE TYPES
---------------
For each of the types listed below, if either object is of the given
type, the two objects are similar as constants exactly if the other is
of that type and the values of all of the specified attributes are
similar as constants.
The attributes listed here can be called the "Basic Attributes" of
objects of each of these types.
Cons CAR, CDR.
Array For 1-dimensional arrays:
LENGTH, ARRAY-ELEMENT-TYPE, and ELT for all legal indices.
For arrays of other dimensions:
ARRAY-DIMENSIONS, ARRAY-ELEMENT-TYPE, AREF for all legal
indices.
An array of type SIMPLE-ARRAY can only be similar as a
constant to an array of type SIMPLE-ARRAY. However, we
allow the file-compiler a bit of latitude here. Where
constants in source code are displaced, have fill
pointers, or are adjustable, constants in the code
resulting from compilation and loading are permitted to
lack any or all of these qualities.
Hash Table Keys and value pairs. The table's test is unchanged
also. If the file compiler is given a constant containing a
a hash table that has keys that are similar as
constants, the consequences are undefined.
Consider a hash table as an unordered set of key and
value pairs. Two hash tables are similar as constants
exactly if there is a one-to-one correspondence between
the key and value pairs of each and a one-to-one
correspondence between the uninterned symbols of each
such that the two keys of each corresponding pair are
similar as constants and the two values are also similar
as constants. The correspondence of uninterned symbols
must be consistent with the correspondence defined for
the entire set of constants in the file.
Pathname Each pathname component.
OTHER TYPES
-----------
Stream, Compiled-Function, Readtable, Generic-function, Method
Objects of these types are not supported in compiled
constants.
Function Only function constants that are not compiled-functions
and do not close over any (lexical) variables are
supported in compiled constants.
Two such functions are similar as constants if their
SOURCE-LAMBDA-EXPRESSIONs are similar as constants.
Structure, Standard-object
<<There is a cl-cleanup issue, LOAD-OBJECTS, pending
which proposes a mechanism for dealing with objects.>>
For structure instances with no method defined at compile
time for MAKE-LOAD-FORM, the slot values and the name of
structure type (a symbol reference) are recorded by the
compiler and reconstructed by the loader.
Examples:
If source code contains a constant that could PRINT as (#1=#:FOO
#2=#:FOO #1# #2#), the constant resulting from compiling and loading
that code would have to be PRINTable as (#1=#:FOO #2=#:FOO #1# #2#).
If we make a hash table H, set three variables A, B, and C to
different uninterned symbols named FOO, and enter keys and values as
follows:
(setf (gethash a h) b)
(setf (gethash b h) a)
(setf (gethash c h) c)
If H appears in a compiled constant, after compiling and loading it,
(let ((value (list)))
(maphash #'(lambda (x y) (push (list x y) value)) h)
value)
could print as
((#1=#:FOO #2=#:FOO) (#2# #1#) (#3=#:FOO #3#))
but not as
((#1=#:FOO #2=#:FOO) (#2# #3=#:FOO) (#3# #1#))
Rationale:
For the benefit of users, this proposal tries to define a fairly large
set of types that all Common Lisp implementations are to handle. It
also attempts to leave room for implementations to differ. Some
implementations have made opposing choices because the language
doesn't specify one over the other. Some implementations already
handle constants that this proposal defines as not legal in Common
Lisp programs, and that is useful to users of those systems.
Different implementors have different amounts of resources to apply to
their system, and implementations differ in their whole approach in
some cases.
This proposal appears to reflect user demand and appears not to exceed
the capabilities of most implementations of the language.
The proposal ensures that all references to the same uninterned symbol
within a file will all map to references to just one uninterned symbol
after compiling and loading. This is needed to support PCL.
Current practice:
>From Gail Zacharias (Nov 14): "Coral pretty much implements this
proposal (I think we currently coalesce hash table keys, but that's
just a bug that will be fixed). We also fasdump packages (using the
package name) and compiled functions (but not foreign functions). For
symbols, we dump the name, and if (roughly speaking) the symbol would
get printed with a package prefix, we also dump the package name and
load the symbol into that package (otherwise it gets loaded into the
current load-time package)."
>From David Gray (Nov 9): "The Explorer can compile constant functions,
read tables, and hash tables; an error is signalled for a stream. A
package object used to break the compiler but in release 5 it has been
fixed to generate instructions to call FIND-PACKAGE on the package
name at load time." (Nov 15): [The Explorer does not guarantee
retention of displaced-to and displaced-index-offset attributes.]
"The Explorer also does not currently support dumping closures (either
compiled or evaluated), although non-closure compiled functions can be
dumped."
>From David Moon (Jan 24): "Symbolics Genera current practice: aside
from some current bugs we have with circular structures of certain
types and with preserving the identity of CONSes under EQ, this is
more or less consistent with our current practice, if you made the
changes implied by my earlier comments. We preserve the :displaced-to
and :fill-pointer array attributes. I doubt that we do what the
proposal says for hash-tables, readtables, and random-states. We
support dumping compiled and interpreted functions, but not closures,
which in effect means we don't support dumping functions."
>From Sandra Loosemore (Mar 3): "UCL currently can handle only
constants that are of type number, character, symbol, cons,
simple-vector, or string (which it turns into simple-string). It
signals an error if an attempt is made to compile any other kind of
object as a constant."
Adoption cost:
Not known. Probably moderate or low -- for most implementations. The
cost would be to implementors rather than users since this part of the
language is currently underspecified. The author believes the cost
will be reasonable for KCL, an implementation where there is some
concern about this issue.
This proposal is close to compatible with the Franz, Lucid, Coral,
Texas Instruments, and Symbolics implementations. It is probably
compatible or nearly compatible with other "Lisp Machine"
implementations.
Benefits:
Users would be able to use aggregate objects in constants with
confidence about the behavior of their code.
Conversion cost:
Where this proposal *requires* different behavior than an existing
implementation, there is a conversion cost for users of that
implementation. It appears that this cost will be small, less than
the cost of leaving things unspecified.
Esthetics:
Since there is no adequate definition at present, a fuller definition
would be more esthetic.
Discussion:
This proposal does leave some user-visible attributes of objects
unspecified across the compile-and-load process, except that they must
be consistent with the attributes that must be retained. This
situation is a compromise between the desire for full specification on
the one hand, and on the other hand the desire to leave freedom for
different implementations to remain different and to support some
optimizations such as compacting hash tables and "simplifying" arrays.
Proposals will be entertained for tighter specification of datatypes
such as arrays.
The full extension of the concept of coalescing of constants is to say
that they can be coalesced exactly when they are similar as constants.
Comparing functions semantically is intertwined with the specification
of what conforming programs and implementations are allowed to do.
This proposal does not attempt to do that since compiled functions are
not supported by this proposal in compiled constants.
The definition of similarity for random-states supports the
possibility of random states that are immutable because of being in
compiled constants.
Readtables need not be supported by an implementation. If a readtable
contains only symbols to represent functions, here is Cris Perdue's
suggested spec for similarity of readtables:
Character syntax type for each character in the table;
function for each readmacro character, mappings for
dispatch macros; whether terminating or nonterminating
for each readmacro.
Interest has been expressed by a number of people including users, in
support for user-definable "dumping" of CLOS objects and structure
instances. The cleanup issue LOAD-OBJECTS deals with this.
This subsumes the issue CONSTANT-ARRAY-ATTRIBUTES.
Sandra Loosemore says:
I plan to submit an amendment to this proposal which would remove the
requirement that the compiler be able to dump non-compiled, non-closed
functions. The reason for removing this requirement is that there is
no way to portably construct an object which is guaranteed to be a
non-compiled, non-closed function. Note that implementations are
permitted to make all functions COMPILED-FUNCTIONs.
JonL White notes:
The analogy between FIND-PACKAGE and FIND-CLASS suggests that class
objects are in the same "database" category as packages. Shouldn't
they be referenced "by name" in compiled file?
Moon responds:
In Flavors we generate metaobjects at compile time, but we never put
them (to speak loosely) into the compiled-code file; instead macros
like DEFFLAVOR and DEFMETHOD expand into Lisp code that obtains new
metaobjects at load time, based on the class name and generic function
name. I don't see how any other way could work, actually, since two
distinct compiled files that refer to a class by the same name must
end up referring to the same metaobject after loading. In Flavors we
don't have anonymous classes nor anonymous generic functions, so we
don't have to solve those issues.
[Issue LOAD-OBJECTS proposes] that the way to load an instance of a
standard-class from a compiled file is for a method of the instance
to return a form which is then evaluated at load time. The semantics
of loading an instance of a standard-class from a compiled file can be
entirely understood in terms of MAKE-INSTANCE or whatever other
function is called by the form returned by MAKE-LOAD-FORM; no new
concepts need be introduced. If the programmer of a given class wants
to use the class redefinition protocol, that class's MAKE-LOAD-FORM
method can output something that uses that protocol, and if he
doesn't, it can output something that doesn't.
-------
∂05-Mar-89 1819 CL-Compiler-mailer subcommittee meeting
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Mar 89 18:19:38 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551042; Sun 5-Mar-89 21:16:49 EST
Date: Sun, 5 Mar 89 21:16 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: subcommittee meeting
To: sandra%defun@CS.Utah.EDU
cc: CL-Compiler@SAIL.Stanford.EDU, cperdue@Sun.COM
In-Reply-To: <8903060050.AA05731@defun.utah.edu>
Message-ID: <890305211639.5.KMP@BOBOLINK.SCRC.Symbolics.COM>
CL-Editorial is tentatively planning to meet Monday evening. If both
met simultaneously, I would probably attend the editorial meeting. My
presence is not an essential part of the meeting, of course, but I
figured I'd mention the conflict -- especially since others might have
it, too.
If you're not reporting until Wednesday, why not plan to meet after
hours Tuesday?
∂05-Mar-89 1837 CL-Compiler-mailer Re: subcommittee meeting
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 5 Mar 89 18:37:37 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA03552; Sun, 5 Mar 89 19:35:30 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA05943; Sun, 5 Mar 89 19:35:26 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903060235.AA05943@defun.utah.edu>
Date: Sun, 5 Mar 89 19:35:23 MST
Subject: Re: subcommittee meeting
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU, cperdue@Sun.COM
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Sun, 5 Mar 89 21:16 EST
Yes, a Tuesday evening meeting is also a possibility. Let's try to be
flexible about it until we see what people's travel plans are like and
what (and how many) issues are still causing us trouble.
-Sandra
-------
∂05-Mar-89 1917 CL-Compiler-mailer cl-compiler issue status, as of 3/5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 5 Mar 89 19:17:25 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA04133; Sun, 5 Mar 89 20:15:24 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA06000; Sun, 5 Mar 89 20:15:21 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903060315.AA06000@defun.utah.edu>
Date: Sun, 5 Mar 89 20:15:18 MST
Subject: cl-compiler issue status, as of 3/5
To: cl-compiler@sail.stanford.edu
Here's a quick summary of active cl-compiler issues.
These issues seem to be in pretty good shape right now. I know some
of them will need minor changes to the writeup before they are
released, mostly relating to updating current practice and tightening
up error language. Some of them haven't gotten much comment since the
last version was distributed.
COMPILE-FILE-SYMBOL-HANDLING
(Except for possible flames from JonL?)
COMPILED-FUNCTION-REQUIREMENTS
COMPILER-DIAGNOSTICS
COMPILER-VERBOSITY
CONSTANT-CIRCULAR-COMPILATION
CONSTANT-COLLAPSING
CONSTANT-COMPILABLE-TYPES
LOAD-TIME-EVAL
MACRO-CACHING
MACRO-ENVIRONMENT-EXTENT
(Except for conflicting reports about what CLOS assumes.)
QUOTE-SEMANTICS
The writeups for the following issues still need major revisions. These
are the ones I personally think are important and am going to try to finish
up in time to be voted on.
CLOS-MACRO-COMPILATION
(New issue on compile-time behavior of CLOS defining macros,
waiting for input from CLOS committee.)
COMPILE-ENVIRONMENT-CONSISTENCY
(The new version of the writeup is complete except for the CLOS
section.)
COMPILER-LET-CONFUSION
(Probably present both ELIMINATE and REPAIR proposals but add Kim's
SYMBOL-MACROLET technique to the presentation.)
DEFINING-MACROS-NON-TOP-LEVEL
(Needs to be updated to match EVAL-WHEN-NON-TOP-LEVEL.)
EVAL-WHEN-NON-TOP-LEVEL
(We need to try to reach closure on this, or agree to present more than
one proposal.)
These are issues where the writeups still need major revisions but
somebody else is going to have to work on them. (I certainly don't
want to discourage anybody from doing so.)
COMPILE-FILE-ENVIRONMENT
DEFCONSTANT-NOT-WIRED
DEFINE-OPTIMIZER
PROCLAIM-ETC-IN-COMPILE-FILE
SYNTACTIC-ENVIRONMENT-ACCESS (aka MACRO-ENVIRONMENT-CREATOR)
WITH-COMPILATION-UNIT
-Sandra
-------
∂06-Mar-89 1622 CL-Compiler-mailer Re: COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 6 Mar 89 16:22:47 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA25042; Mon, 6 Mar 89 11:28:36 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA06794; Mon, 6 Mar 89 11:24:22 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA04038; Mon, 6 Mar 89 11:27:43 PST
Date: Mon, 6 Mar 89 11:27:43 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903061927.AA04038@clam.sun.com>
To: sandra%clam@Sun.COM
Subject: Re: COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE
Cc: cl-compiler@sail.stanford.edu
This proposal came out differently than I expected:
"When a compiled file is loaded, the interned symbols it
references are found by calling INTERN at load time with two arguments,
the name of the symbol and the package with the same name as
the compile-time symbol's home package. ... "
This doesn't ensure that the home package remains the same across
compilation and loading, which I consider the key consideration.
How about this statement instead?
"When a file is compiled, the symbol name is recorded together
with the home package name and an indication of whether the
symbol is external in its home package. At load time the
symbol is effectively looked up with:
(find-symbol string (find-package pkg-name))
If the symbol is noted as external, it must be found at load
time as :external. If it is noted as internal, it must either
be present in the package or not found at all. If it is not found
at all, it is created as if by:
(intern string (find-package pkg-name))
If the package system is not in a suitable state, an error is
signalled."
Here is some code that purports to do the right thing:
(defun resolve-symbol (name pkg-name external?)
(multiple-value-bind (sym where)
(find-symbol string (find-package pkg-name))
(if external?
(if (eq where :external) sym <signal error>)
(case where
((:internal :external) sym)
(nil (intern string (find-package pkg-name)))
(otherwise <signal error>)))))
---------------------------
This is what I consider "the right thing". I'd like to see it
given as one of the alternative proposals if it isn't already what
was intended by proposal HOME-PACKAGE.
-Cris
∂06-Mar-89 1711 CL-Compiler-mailer Re: COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 6 Mar 89 17:11:38 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA08531; Mon, 6 Mar 89 18:09:33 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA06924; Mon, 6 Mar 89 18:09:30 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903070109.AA06924@defun.utah.edu>
Date: Mon, 6 Mar 89 18:09:29 MST
Subject: Re: COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE
To: cperdue@Sun.COM (Cris Perdue)
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: cperdue@Sun.COM (Cris Perdue), Mon, 6 Mar 89 11:27:43 PST
What you describe is not what proposal HOME-PACKAGE was intended to
say. It is, however, a behavior that I would consider reasonable. It
has the benefit of offering somewhat tighter error checking, but the
disadvantage that it is even less forgiving of minor changes to the
package structure than proposal HOME-PACKAGE. For example, suppose
you compile your file in package P1 that uses the P2 package, and you
reference a symbol FOO whose home package is P1. If, between compile
and load time, another symbol called FOO is exported from the P2
package, you lose.
If there is a strong belief that this behavior is correct, I don't
have any objection to adding it as another proposal and/or modifying
proposal REQUIRE-CONSISTENCY to allow this as a legitimate
implementation technique, other than that it's a lot of work. :-)
-Sandra
-------
∂06-Mar-89 1711 CL-Compiler-mailer issue LOAD-TIME-EVAL, version 10
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89 17:10:17 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551813; Mon 6-Mar-89 20:07:29 EST
Date: Mon, 6 Mar 89 20:07 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue LOAD-TIME-EVAL, version 10
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8903021823.AA03273@defun.utah.edu>
Message-ID: <19890307010708.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
I've read this and have no further comments, except that the
differences between the two proposals would be easier to
understand if they were stated explicitly. It's hard to compare
two multi-page pieces of text without using a computer.
∂06-Mar-89 1812 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89 18:11:53 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551857; Mon 6-Mar-89 21:09:20 EST
Date: Mon, 6 Mar 89 21:08 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: cl-compiler@sail.stanford.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8902242327.AA11369@defun.utah.edu>
Message-ID: <19890307020856.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 24 Feb 89 16:27:57 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Here is a draft of an alternate EVAL-WHEN proposal.
I am open to suggestions on this writeup. If everybody else hates
this and thinks that the the general direction here is totally wrong,
I will shut up and go along with the GENERALIZE-EVAL proposal. But I
personally would like to see something like this included in the
writeup we send out to X3J13 to vote on.
I know I'm not "everybody else," but I think the general direction here
is wrong. Here's your rationale:
Rationale:
This behavior specified by this proposal is simple and easy to
understand, and extends the behavior of EVAL-WHEN usefully to
non-top-level situations. It is largely compatible with the behavior
of EVAL-WHEN specified in CLtL, except for the situation shown in
example #6 above. Some people find the nesting behavior of EVAL-WHEN
specified in this proposal to be an improvement over that specified
in CLtL.
This gives a useful meaning to EVAL-WHEN that supports useful and
predictable behavior if defining macros are used in a non-top-level
situation.
It's true that this extends to non-top-level situations, but I don't
believe that is either simple or easy to understand, as compared with
what CLtL says (or the version 5 proposal by Pitman and Moon that
extends CLtL to non-top-level situations). I suppose that is a matter
of taste, but here's a specific example: In CLtL, if you want to make
a top-level form do what it always does and also happen at compile
time, you wrap (eval-when (eval load compile) ...) around it. That
works. In this proposal, eval-when always makes its body non-top-level,
which means that it is impossible to make a top-level form do what
it always does, plus something else, by wrapping an eval-when around it.
To me that makes it complicated and hard to understand. I also think
the new shielded/unshielded concept is obfuscation.
Aside from that, I am very leary about the idea of changing a part of
the language that works in a way that some people don't like, to work in
a different way that other people don't like, when the semantic issues
are sufficiently complicated and cloudy that nobody can predict the
repercussions of the change. This just seems very dangerous. I would
be the first to admit that CLtL's eval-when feature is not the most
beautiful and well-thought-out language feature to come down the pike.
It also has a remarkably badly chosen set of keywords, which I think
contributes to confusion in the discussion. However, your proposed
alternative doesn't seem to be much better, and suffers from the
disadvantage of not having a user community with five years' experience.
I would much rather be offered the choice of keeping EVAL-WHEN
compatible or switching to something different and obviously correct.
But I think the choice here is between keeping EVAL-WHEN compatible and
switching to something that's just different.
However, here's my real problem with all this. I'm trying to figure out
what the standard should say about the expansion of the CLOS
defining-form macros. I know that they should be defined in terms of
EVAL-WHEN. The continuing instability of EVAL-WHEN, and the large
amount of mail to plow through, is really interfering with my ability to
figure anything out. That may well say more about me than about
EVAL-WHEN, but it's still a fact. I wish I could force myself to ignore
everything you're doing and just use the CLtL definition of EVAL-WHEN
for now.
∂06-Mar-89 1840 Common-Lisp-Object-System-mailer remote environments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89 18:39:50 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551871; Mon 6-Mar-89 21:37:29 EST
Date: Mon, 6 Mar 89 21:37 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: remote environments
To: David N Gray <Gray@DSG.csc.ti.com>
cc: Common-Lisp-Object-System@SAIL.Stanford.edu, CL-Compiler@SAIL.Stanford.edu
In-Reply-To: <2813272681-7847725@Kelvin>
Message-ID: <19890307023706.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 23 Feb 89 18:38:01 CST
From: David N Gray <Gray@DSG.csc.ti.com>
I think it might help to focus the discussion about remote environments
and meta object programming if we had a clearer picture of what the
goals are. The basic question is what kinds of things can be defined and
then used during compilation of the same file that defines them, and
what restrictions might apply.
I think you're right. Let me offer my opinions on the set of issues
you have articulated.
DEFCLASS
* Can the class be used as a superclass of a later DEFCLASS? [clearly yes]
* Can it be used as a specializer in a DEFMETHOD? [clearly yes]
Agreed.
* Can a MAKE-INSTANCE be done by a macro expander, DEFCONSTANT, or "#."?
I have two answers to this, both based on current practice but
contradictory. One is that I have some users who really need to be able
to instantiate such classes in macro expanders. They have an embedded
language which has an object-oriented representation for programs;
therefore macro expansions include instances of classes defined earlier
in the same file. The second is that Flavors does not support
instantiation of compile-time classes in the Symbolics implementation,
consequently the users I mentioned are currently operating with a kludge.
I think it would be much nicer if we could make compile-time classes
instantiable. However, I agree that it would not ruin the language to
omit that feature if we can't figure out how to do it.
- If so, do initforms have access to macros and constants defined
earlier in the file?
Initforms certainly have access to those things since they are included
in the initforms' environment. I think 88-002R implies this.
* Can the class be used as the :METACLASS option of a later DEFCLASS?
- Can that second class be instantiated?
* Can it be used as the :GENERIC-FUNCTION-CLASS option of a
DEFGENERIC, GENERIC-FUNCTION, GENERIC-FLET, or GENERIC-LABELS?
* Can it be used as the :METHOD-CLASS option of a DEFGENERIC etc.?
- Can DEFMETHODs then be done for that generic function?
The answers to these three should be the same and should depend just on
whether a remote (aka compile-time) class can be instantiated. If yes,
then the subsidiary questions are clearly also yes.
DEFGENERIC
* Referenced by later DEFMETHOD? [clearly yes]
* Is the function defined such that it can be called at compile time?
Clearly not, since a DEFUN is not. Here I think we should defer to the
definition of how COMPILE-FILE deals with DEFUN and not try to propose
something "better" that is just for CLOS. In fact I do have something
better in mind, in which COMPILE-FILE would be less different from
normal Lisp evaluation. But I don't think it would be appropriate to
propose something so radical for Common Lisp at its current life stage.
DEFMETHOD
* Can it be invoked at compile-time?
* In particular, will methods added to standard generic functions be
invoked by the system at compile time?
No, and no, for the same reason.
When you compile-file a DEFMETHOD, a method metaobject is created but it
is not added to the generic-function metaobject in the local environment.
Instead it is added to a different generic-function metaobject created
in the remote environment. That's my model of what has to happen. Note
that this should be completely consistent with the way that compile-file
of a DEFCLASS, with a direct superclass whose name is defined in the
local environment and not in the remote environment, does not add the
new class metaobject to the direct subclasses of the local superclass,
but rather to a different object. (I realize we haven't agreed on what
this paragraph says, or even seen a coherent proposal, yet. I'm just
telling you my model.)
DEFINE-METHOD-COMBINATION
* Used in a later DEFGENERIC?
- Callable at compile-time?
I believe this should be yes to both, although if I'm not mistaken
Flavors does not allow it. I think that's a bad design choice in
Flavors.
Are there other interactions that need to be considered?
I can make a few other points. Assuming remote classes can be
instantiated, remote methods specialized to a remote class of course
cannot be executed. However, nothing stops us from making a local
method specialized to a remote class. There happens not to be a
defmethod syntax for doing that [although in fact one could imagine
such an extension], but it should be easy to do with the interface
at the next level down. That's a benefit from the clear separation
between names and objects for which CLOS is striving.
In the past there has been some controversy about whether the remote
environment can inherit from the local environment. I think this is
crystal clear: since some user-defined classes have STANDARD-OBJECT
as a direct superclass, and STANDARD-OBJECT is not defined in the same
file, the remote environment is clearly inheriting from the local
environment. Different implementations might want to address the
details of this differently, but I think it's clear that there has to
be provision for it in the metaobject model. It makes things more
complicated, but that's unavoidable.
I think that the standard could take a simple, minimal, approach that
would still satisfy the most common usages. Suppose we said:
DEFCLASS
If it appears at top-level, then the class name is defined for use as
a type specifier or method specializer. It can also be used as a
superclass of a later DEFCLASS since they don't have to be defined
before being referenced anyway. The class object can be obtained by
calling FIND-CLASS with an environment argument, but it can only be
used in ways that do not require the class to be finalized. For
example, one could ask for its CLASS-DIRECT-SUPERCLASSES, but not its
CLASS-PRECEDENCE-LIST. Other uses, which could involve the need to
instantiate the class, could not be portably done in the same file
without wrapping an (EVAL-WHEN (EVAL COMPILE LOAD) ...) around the
DEFCLASS. Implementations would be free to support compile-time
instantiation as an extension. One way to look at this would be to
say that it is implementation-dependent whether FINALIZE-INHERITANCE
works or signals an error when given a class defined in the
compile-time environment.
[And no compile-time generic-function or method objects at all]
This is an interesting idea, but I think it's too restrictive. Here's a
plausible and many-times proposed application for metaobjects which
would not be possible if we adopted this idea. Suppose you made an
optimizing compiler that is allowed to assume that no class
redefinitions, no method redefinitions, and no newly-defined subclasses
will be created at run time. The compiler is to take advantage of this
constraint on the program to generate more efficient code by doing type
propagation and constant-folding out many method lookups and slot
lookups. One should expect many CLOS programs compiled this way to have
the same efficiency as C++ without suffering the same restrictions
during development. Now, the natural way to organize the datastructures
in this compiler is as metaobjects. CLOS (chapter 3 at least) already
defines how to access the information the compiler needs. The
constraint against run-time redefinition means the compiler can assume
certain functions of metaobjects return the same result at compile time
as they must at run time. For this to work all the metaobjects must
exist and finalization must possible. It doesn't appear that
instantiation is required, assuming the program being compiled doesn't
define any metaclasses.
I hope to keep thinking in this direction.
∂06-Mar-89 2146 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 6 Mar 89 21:46:33 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA15544; Mon, 6 Mar 89 22:44:22 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA07259; Mon, 6 Mar 89 22:44:01 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903070544.AA07259@defun.utah.edu>
Date: Mon, 6 Mar 89 22:43:59 MST
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>,
cl-compiler@sail.stanford.edu
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Mon, 6 Mar 89 21:08 EST
Your concerns have been noted. In response, I want to say that the
reason why I've been pursuing this is that I just don't feel
completely comfortable with the GENERALIZE-EVAL proposal and I haven't
entirely given up hope of coming up with something better. That you
need such a large piece of pseudocode, two state variables, plus a
table to describe the nesting behavior to specify how EVAL-WHEN works
bothers me because it's an indication of just how complicated the
semantics are. The semantics make as much sense as any of the other
alternatives we've considered, but I still wish we could come up with
a less complicated model of how EVAL-WHEN behaves.
On the other hand, I realize that my alternate proposal doesn't
represent a vast improvement and that we are running out of time to
come up with radically different alternatives. If those of us who
still have reservations about the GENERALIZE-EVAL proposal haven't
reached consensus (or at least major progress in that direction) on an
alternative by the end of the week, there won't be one on the ballot.
Please, go ahead and formulate your model of how the CLOS macros work
in terms of the GENERALIZE-EVAL proposal. Once we have something
specific in hand there, it will be easier for all of us to understand
what the interactions between the two issues might be.
-Sandra
-------
∂06-Mar-89 2243 CL-Compiler-mailer Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
Received: from ti.com by SAIL.Stanford.EDU with TCP; 6 Mar 89 22:42:33 PST
Received: by ti.com id AA03025; Mon, 6 Mar 89 12:19:38 CST
Received: from Kelvin by tilde id AA05183; Mon, 6 Mar 89 12:06:37 CST
Message-Id: <2814199584-13822129@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 6 Mar 89 12:06:24 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU, Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)
In-Reply-To: Msg of Fri, 24 Feb 89 14:08 EST from Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
> I wasn't intending my :EXECUTE to be different from your :EXECUTE. I'm
> not sure if I just used a poor choice of words to describe it or if I've
> missed some subtlety of your proposal.
>
> LOAD and COMPILE have meaning only when in a non-top-level position.
> EVAL has meaning only in a top-level position.
OK, I see now that I did miss noticing the sentence in your proposal that
says:
The use of EVAL controls whether processing occurs for
non-top-level forms.
But this just makes the proposal even more incompatible that I thought
before.
> For any given context, if LOAD is `being considered,' then COMPILE is
> `being considered' -- and vice versa.
>
> For any given context, if LOAD and COMPILE are `being considered' then
> EVAL is not `being considered' -- and vice versa.
...
I found this discussion to be incomprehensible until I did a text
substitution to replace EVAL, COMPILE, and LOAD with your alternate names
:EXECUTE, :COMPILE-TOPLEVEL, and :LOAD-TOPLEVEL. Then it began to make
sense. It just isn't going to work to define new meanings for old words;
if this approach is going to be taken, then new names are essential.
Also, to help make this clearer, instead of :EXECUTE, it should be
something like :EXECUTE-NON-TOP-LEVEL.
Now that I understand the proposal, I still need to think about whether I
agree with it.
∂06-Mar-89 2354 CL-Compiler-mailer Issue: SAFE-CODE (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89 23:54:11 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551956; Tue 7-Mar-89 02:51:39 EST
Date: Tue, 7 Mar 89 02:51 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: SAFE-CODE (Version 1)
To: CL-Compiler@SAIL.Stanford.EDU
Message-ID: <890307025131.8.KMP@BOBOLINK.SCRC.Symbolics.COM>
Issue: SAFE-CODE
Forum: Compiler
References: OPTIMIZE declaration (p160),
Issue ERROR-TERMINOLOGY
Category: CLARIFICATION/CHANGE
Edit history: 07-Mar-89, Version 1 by Pitman
Status: For Internal Discussion
Problem Description:
The new error terminology refers to ``safe code'' in the definition
of the term and CLtL refers to
individual meanings of OPTIMIZE qualities, but there is no standardized
way of relating the two concepts.
Proposal (SAFE-CODE:SAFETY-3):
Define that, formally, the term ``safe code'' is code refers to any
code in which the OPTIMIZE quality for SAFETY has a value of 3.
Implementors might wish to consider treating other situations as safe
as well, but in making that decision both the relative values of other
OPTIMIZE qualities and the idiosyncratic properties of the particular
implementation should also be taken into account.
Examples:
1. The body of the following is safe...
a. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 3))) . body)
b. (LOCALLY (DECLARE (OPTIMIZE SAFETY )) . body)
2. The body in each of the following is unsafe. They might
or might not be treated as safe, possibly depending
on the values of other qualities and specifics of the
implementation.
a. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 0))) . body)
b. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 1))) . body)
c. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 2))) . body)
Rationale:
Programmers will probably intuitively expect that the term
``highest safety'' refers to giving the SAFETY quality its
highest safety.
Current Practice:
Implementors ...
Symbolics Genera does error checking always, and ignores OPTIMIZE
declarations.
Symbolics Cloe heeds OPTIMIZE declarations, but effectively makes
`judgment calls' in every case because there is no clear guidance
on how to interpret them.
Programmers ...
Many programmers write (DECLARE (SPEED 0) (SAFETY 3)) even when all
they really want to control is SAFETY because they are afraid that
unless they explicitly sacrifice speed, the compiler will ignore
their plea for error checking.
Cost to Implementors:
Some implementations might require a lot of nitpicky little changes.
Cost to Users:
Technically none. No portable code can really rely on much of any
reliable effect out of any of the OPTIMIZE qualities. However, some
users may rely on implementation-specific features of implementations,
and if those implementations are forced to change, non-portable user
code might break in some ways.
Cost of Non-Adoption:
The meaning of ``safe code'' will not be clearly defined.
Benefits:
Programmers will be able to say what they mean. They can stop
superstitiously putting (SPEED 0) next to (SAFETY 3) just to
assure they get safe code.
Aesthetics:
Improved. This will make the English align well with the code.
Discussion:
It is very important that we reach consensus in some form on this issue.
Pitman supports SAFE-CODE:SAFETY-3.
∂07-Mar-89 0727 CL-Compiler-mailer Re: Issue: SAFE-CODE (Version 1)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 7 Mar 89 07:27:32 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA25432; Tue, 7 Mar 89 08:25:28 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA07523; Tue, 7 Mar 89 08:25:22 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903071525.AA07523@defun.utah.edu>
Date: Tue, 7 Mar 89 08:25:20 MST
Subject: Re: Issue: SAFE-CODE (Version 1)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 7 Mar 89 02:51 EST
Actually, I was one of the people who thought this was "intuitively
obvious", but an explicit statement sounds like a good idea. Thanks
for writing this up.
-Sandra
-------
∂07-Mar-89 0808 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 7 Mar 89 08:06:20 PST
Received: from mist.encore.COM by multimax.encore.com with SMTP (5.61/25-eef)
id AA17032; Tue, 7 Mar 89 11:04:40 -0500
Received: from localhost by mist. (4.0/SMI-4.0)
id AA16212; Tue, 7 Mar 89 11:02:48 EST
Message-Id: <8903071602.AA16212@mist.>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: cl-compiler@sail.stanford.edu
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
In-Reply-To: Your message of Mon, 06 Mar 89 21:08:00 -0500.
<19890307020856.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 07 Mar 89 11:02:42 EST
From: Dan L. Pierson <pierson@mist.encore.com>
Date: Mon, 6 Mar 89 21:08 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
However, here's my real problem with all this. I'm trying to figure out
what the standard should say about the expansion of the CLOS
defining-form macros. I know that they should be defined in terms of
EVAL-WHEN. The continuing instability of EVAL-WHEN, and the large
amount of mail to plow through, is really interfering with my ability to
figure anything out. That may well say more about me than about
EVAL-WHEN, but it's still a fact. I wish I could force myself to ignore
everything you're doing and just use the CLtL definition of EVAL-WHEN
for now.
You're right, this has dragged on much too long. Since
GENERALIZE-EVAL-NEW-KEYWORDS in Version 5 seems to be the best
proposal so far, I support it. I'm not as opposed to Sandra's new
proposal as you are; but since I also don't see any major advantages
to it, the incompatibility isn't worth it.
I would very much like to see what GENERALIZE-EVAL-NEW-KEYWORDS will
do to DEFINING-MACROS-NON-TOP-LEVEL before voting for the former. I
still want to be able to wrap a LET around a couple of DEFUNs and have
it all work correctly!
∂07-Mar-89 0828 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 7 Mar 89 08:28:15 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA27258; Tue, 7 Mar 89 09:26:05 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA07624; Tue, 7 Mar 89 09:26:03 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903071626.AA07624@defun.utah.edu>
Date: Tue, 7 Mar 89 09:26:01 MST
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL
To: Dan L. Pierson <pierson@mist.encore.com>
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Dan L. Pierson <pierson@mist.encore.com>, Tue, 07 Mar 89 11:02:42 EST
> Date: Tue, 07 Mar 89 11:02:42 EST
> From: Dan L. Pierson <pierson@mist.encore.com>
>
> I would very much like to see what GENERALIZE-EVAL-NEW-KEYWORDS will
> do to DEFINING-MACROS-NON-TOP-LEVEL before voting for the former. I
> still want to be able to wrap a LET around a couple of DEFUNs and have
> it all work correctly!
Right. I think we are all agreed that the rules for when defining
macros cause compile-time magic should be exactly the same as those
for when (EVAL-WHEN (COMPILE) ...) causes compile-time magic,
precisely so that you can implement the defining macros using
EVAL-WHEN.
The only major change I'm planning to do the the existing writeup is
to move the definition of "top-level" versus "non-top-level" to issue
EVAL-WHEN-NON-TOP-LEVEL. I think it really makes more sense there,
since that is where the COMPILE-FILE model is presented.
-Sandra
-------
∂07-Mar-89 0912 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 7 Mar 89 09:11:58 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 552137; Tue 7-Mar-89 12:09:05 EST
Date: Tue, 7 Mar 89 12:08 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: Dan L. Pierson <pierson@mist.encore.com>
cc: cl-compiler@sail.stanford.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <8903071602.AA16212@mist.>
Message-ID: <19890307170826.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 07 Mar 89 11:02:42 EST
From: Dan L. Pierson <pierson@mist.encore.com>
I would very much like to see what GENERALIZE-EVAL-NEW-KEYWORDS will
do to DEFINING-MACROS-NON-TOP-LEVEL before voting for the former. I
still want to be able to wrap a LET around a couple of DEFUNs and have
it all work correctly!
That's difficult to answer, since the last version of
EVAL-WHEN-NON-TOP-LEVEL archived here is version 7, which the compiler
committee said in Kauai they were going to rewrite. However, here is
the proposal section from version 7, with my comments interleaved.
I will ignore the new-keywords versus keep-the-old-names issue, as
that clearly affects only the appearance of code, not the semantics.
Proposal: DEFINING-MACROS-NON-TOP-LEVEL:ALLOW
(1) Remove the language from p. 66 of CLtL quoted above. Clarify that
while defining macros normally appear at top level, it is meaningful
to place them in non-top-level contexts and that the compiler must
handle them properly in all situations. However, the compile-time side
effects described in issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
only take place when the defining macros appear at top-level.
True under all EVAL-WHEN proposals.
(2) Remove the language on p. 145 of CLtL, which states that macro
functions are always defined in the null lexical environment. Clarify
that all defining macros which create functional objects (including
DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
DEFSETF, as well as DEFUN) must ensure that those functions are
defined in the lexical environment in which the defining form is
evaluated.
True under all EVAL-WHEN proposals except for the one (no longer extant
I believe) that said that the body of an EVAL-WHEN is executed in the
null lexical environment rather than the lexical environment surrounding
the EVAL-WHEN.
(3) Define a ``top-level form'' as follows:
- Each form read by COMPILE-FILE from the input file is a top-level
form.
- Forms within the body of a top-level PROGN, EVAL-WHEN, or
COMPILER-LET are also top-level forms.
- The expansion of a top-level macro call is also a top-level form.
True under the EVAL-WHEN proposal that I like. The second bullet is
false under the EVAL-WHEN proposal that Sandra likes, since the body of
a top-level EVAL-WHEN is not a top-level form under that proposal.
Top-level forms would be evaluated by the interpreter in a null
lexical environment, but evaluation in a null lexical environment does
not necessarily imply that the form is top-level.
True under all EVAL-WHEN proposals.
(4) Specify that top-level forms in a file being compiled are
guaranteed to be processed sequentially, including forms within the
body of a top-level PROGN, EVAL-WHEN, or COMPILER-LET. The order in
which non-top-level subforms of a top-level form are processed by the
compiler is explicitly left unspecified.
Not affected by EVAL-WHEN proposals.
So I think the effect on DEFINING-MACROS-NON-TOP-LEVEL is none other
than avoiding breaking it by violating its assumptions about EVAL-WHEN.
Of course if there is a rewritten DEFINING-MACROS-NON-TOP-LEVEL that
I have not seen (I am not on the compiler committee), the story might
be different.
∂07-Mar-89 0924 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Mar 89 09:24:22 PST
Received: from blacksox ([192.9.201.39]) by heavens-gate.lucid.com id AA03343g; Tue, 7 Mar 89 09:17:00 PST
Received: by blacksox id AA01657g; Tue, 7 Mar 89 09:21:49 PST
Date: Tue, 7 Mar 89 09:21:49 PST
From: Eric Benson <eb@lucid.com>
Message-Id: <8903071721.AA01657@blacksox>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: pierson@mist.encore.com, cl-compiler@sail.stanford.edu,
Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: David A. Moon's message of Tue, 7 Mar 89 12:08 EST <19890307170826.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Date: Tue, 7 Mar 89 12:08 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
(3) Define a ``top-level form'' as follows:
- Each form read by COMPILE-FILE from the input file is a top-level
form.
- Forms within the body of a top-level PROGN, EVAL-WHEN, or
COMPILER-LET are also top-level forms.
Should we include forms within the body of a top-level MACROLET? This
seems reasonable. What about LOCALLY? This also seems reasonable,
modulo the question of whether LOCALLY is a macro or a special form.
Is this a slippery slope?
∂07-Mar-89 0932 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 7 Mar 89 09:32:06 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA29828; Tue, 7 Mar 89 10:29:37 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA07705; Tue, 7 Mar 89 10:29:20 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903071729.AA07705@defun.utah.edu>
Date: Tue, 7 Mar 89 10:29:19 MST
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: Eric Benson <eb@lucid.com>
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, pierson@mist.encore.com,
cl-compiler@sail.stanford.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Eric Benson <eb@lucid.com>, Tue, 7 Mar 89 09:21:49 PST
> Should we include forms within the body of a top-level MACROLET? This
> seems reasonable. What about LOCALLY? This also seems reasonable,
> modulo the question of whether LOCALLY is a macro or a special form.
> Is this a slippery slope?
I think we reached consensus at the last meeting that both MACROLET and
SYMBOL-MACROLET should pass through toplevelness.
LOCALLY is still a sticky issue. I tend to agree with JonL that since
it can add things like SPECIAL declarations to the environment, its
body should never be considered toplevel.
-Sandra
-------
∂07-Mar-89 0942 CL-Compiler-mailer draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Mar 89 09:42:46 PST
Received: from blacksox ([192.9.201.39]) by heavens-gate.lucid.com id AA03379g; Tue, 7 Mar 89 09:35:43 PST
Received: by blacksox id AA01661g; Tue, 7 Mar 89 09:40:29 PST
Date: Tue, 7 Mar 89 09:40:29 PST
From: Eric Benson <eb@lucid.com>
Message-Id: <8903071740.AA01661@blacksox>
To: sandra%defun@cs.utah.edu
Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, pierson@mist.encore.com,
cl-compiler@sail.stanford.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: Sandra J Loosemore's message of Tue, 7 Mar 89 10:29:19 MST <8903071729.AA07705@defun.utah.edu>
Subject: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Date: Tue, 7 Mar 89 10:29:19 MST
LOCALLY is still a sticky issue. I tend to agree with JonL that since
it can add things like SPECIAL declarations to the environment, its
body should never be considered toplevel.
What's wrong with adding SPECIAL declarations? Why is it different
from adding local macros or symbol macros?
∂07-Mar-89 1101 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 7 Mar 89 11:01:05 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 278791; Tue 7-Mar-89 13:30:24 EST
Date: Tue, 7 Mar 89 13:30 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: Eric Benson <eb@lucid.com>, pierson@mist.encore.com, cl-compiler@sail.stanford.edu
In-Reply-To: <8903071729.AA07705@defun.utah.edu>
Message-ID: <19890307183012.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 7 Mar 89 10:29:19 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Should we include forms within the body of a top-level MACROLET? This
> seems reasonable. What about LOCALLY? This also seems reasonable,
> modulo the question of whether LOCALLY is a macro or a special form.
> Is this a slippery slope?
I think we reached consensus at the last meeting that both MACROLET and
SYMBOL-MACROLET should pass through toplevelness.
I thought so too (but I might have thought that only because it was
my own position :-).
LOCALLY is still a sticky issue. I tend to agree with JonL that since
it can add things like SPECIAL declarations to the environment, its
body should never be considered toplevel.
Here is the criterion I prefer to use: a form is non-top-level if its
lexical environment cannot be fully constructed at compile time or if it
is not manifestly executed at load time exactly once. In other words,
the form is enclosed in a variable binding, a block, a tagbody, a loop,
or a conditional. The reason I prefer this criterion is that it is
directly related to the reason we have the kludge of top-level forms in
the language in the first place: compile-file's modelling at compile
time of the actions that will occur at load time.
A lexical environment consists of variables, functions, blocks, go tags,
and declarations. Variables, blocks, and go tags cannot be fully
constructed at load time. Declarations can be fully constructed at
compile time, and functions can also be, unless the definition is a
closure that cannot be fully constructed at compile time; but the way
lexical environments nest in Common Lisp prevents that case from arising
except when the lexical environment of the binding already cannot be
fully constructed at compile time. I think function bindings being
fully constructable at compile time depends on the illegality of using
setf to alter a local function binding, otherwise function bindings
would be just like variable bindings.
Since what LOCALLY adds to the lexical environment can be fully
constructed at compile time, its body should be top-level.
We have tacitly chosen to rule out smart compilers that prove a form is
effectively top-level when a naive compiler might think it was
non-top-level. For example, we require all compilers to treat the defun
in
(let ((x 1))
(defun foo (y)
(expt y 2)))
as non-top-level even though a smart compiler might discover that the
binding of x is irrelevant. Similarly we don't allow a smart compiler
to discover that what appears to be a loop is actually executed exactly
once and treat the forms in its body as top-level. Similarly we don't
allow a smart compiler to "optimize"
(eval '(defun ...)) into (defun ...). I think this was a good decision.
We seem to have added an additional criterion, which is that a form is
non-top-level if its value is used. This means any form that is an
argument to a function, as well as forms appearing in certain special
forms such as DEFPARAMETER, are non-top-level. I think that criterion
may be unnecessary but I have no objection to it. I suspect the reason
for this criterion is nothing more profound than that it allows LOAD's
implementation of the top-level forms to not produce values and hence
to not be nestable inside other top-level forms.
∂07-Mar-89 1140 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 7 Mar 89 11:39:59 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA05094; Tue, 7 Mar 89 12:37:14 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA07782; Tue, 7 Mar 89 12:37:08 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903071937.AA07782@defun.utah.edu>
Date: Tue, 7 Mar 89 12:37:07 MST
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>, Eric Benson <eb@lucid.com>,
pierson@mist.encore.com, cl-compiler@sail.stanford.edu
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 7 Mar 89 13:30 EST
> Date: Tue, 7 Mar 89 13:30 EST
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> Here is the criterion I prefer to use: a form is non-top-level if its
> lexical environment cannot be fully constructed at compile time or if it
> is not manifestly executed at load time exactly once. In other words,
> the form is enclosed in a variable binding, a block, a tagbody, a loop,
> or a conditional.
I would also add "in a FUNCTION special form", although it's unlikely
that anybody would put one directly at top-level. Also, what about
things like CATCH and UNWIND-PROTECT that alter the dynamic
environment?
As other people have noted before, it seems like we are arriving at a
very complicated idea of "top-level" that has very little to do with
people's intuitive notions on the subject. It makes me wonder if
perhaps we shouldn't retreat to a minimalist position where PROGN is
the only special case.
-Sandra
-------
∂07-Mar-89 1418 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 7 Mar 89 14:18:01 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 552433; Tue 7-Mar-89 17:14:33 EST
Date: Tue, 7 Mar 89 17:14 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: Eric Benson <eb@lucid.com>, pierson@mist.encore.com, cl-compiler@sail.stanford.edu
In-Reply-To: <8903071937.AA07782@defun.utah.edu>
Message-ID: <19890307221419.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 7 Mar 89 12:37:07 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Tue, 7 Mar 89 13:30 EST
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> Here is the criterion I prefer to use: a form is non-top-level if its
> lexical environment cannot be fully constructed at compile time or if it
> is not manifestly executed at load time exactly once. In other words,
> the form is enclosed in a variable binding, a block, a tagbody, a loop,
> or a conditional.
I would also add "in a FUNCTION special form", although it's unlikely
that anybody would put one directly at top-level.
I disagree. The immediate "body" of a FUNCTION special form is not a form,
so the concept of "top level form" cannot be relevant to it. The immediate
"body" might be a LAMBDA expression that has forms in its body, but those
inner forms are not manifestly executed exactly once.
Also, what about
things like CATCH and UNWIND-PROTECT that alter the dynamic
environment?
I'd say that these special forms do not manifestly execute their body
exactly once (because they imply throwing out of the middle of the
body), although I admit that there is a fine distinction here.
As other people have noted before, it seems like we are arriving at a
very complicated idea of "top-level" that has very little to do with
people's intuitive notions on the subject.
I vehemently disagree. My message was intended to arrive at a very simple
idea of "top-level" that corresponds exactly to intuitive notions. I was
hoping that this very simple idea would immediately clarify any supposed
issues such as whether the body of a top-level LOCALLY is or is not top-level.
It makes me wonder if
perhaps we shouldn't retreat to a minimalist position where PROGN is
the only special case.
Do we really have to rehearse all the arguments as to why that won't work
once again?
∂07-Mar-89 1423 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 7 Mar 89 14:22:04 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 552440; Tue 7-Mar-89 17:18:50 EST
Date: Tue, 7 Mar 89 17:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: Eric Benson <eb@lucid.com>, pierson@mist.encore.com, cl-compiler@sail.stanford.edu
In-Reply-To: <8903071937.AA07782@defun.utah.edu>
Supersedes: <19890307221419.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890307221837.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 7 Mar 89 12:37:07 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Tue, 7 Mar 89 13:30 EST
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> Here is the criterion I prefer to use: a form is non-top-level if its
> lexical environment cannot be fully constructed at compile time or if it
> is not manifestly executed at load time exactly once. In other words,
> the form is enclosed in a variable binding, a block, a tagbody, a loop,
> or a conditional.
I would also add "in a FUNCTION special form", although it's unlikely
that anybody would put one directly at top-level.
I disagree. The immediate "body" of a FUNCTION special form is not a form,
so the concept of "top level form" cannot be relevant to it. The immediate
"body" might be a LAMBDA expression that has forms in its body, but those
inner forms are not manifestly executed exactly once.
Also, what about
things like CATCH and UNWIND-PROTECT that alter the dynamic
environment?
I'd say that these special forms do not manifestly execute their body
exactly once (because they imply throwing out of the middle of the
body), although I admit that there is a fine distinction here.
As other people have noted before, it seems like we are arriving at a
very complicated idea of "top-level" that has very little to do with
people's intuitive notions on the subject.
I vehemently disagree. My message was intended to arrive at a very simple
idea of "top-level" that corresponds exactly to intuitive notions. I was
hoping that this very simple idea would immediately clarify any supposed
issues such as whether the body of a top-level LOCALLY is or is not top-level.
It makes me wonder if
perhaps we shouldn't retreat to a minimalist position where PROGN is
the only special case.
Do we really have to rehearse all the arguments as to why that won't work
once again?
I'm sorry I flamed so much in this message, but this is the type of response
that makes me wonder if the whole X3J13 effort is nothing but an exercise
in futility.
∂07-Mar-89 1458 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 7 Mar 89 14:58:03 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA18436; Tue, 7 Mar 89 15:55:17 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA08178; Tue, 7 Mar 89 15:55:12 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903072255.AA08178@defun.utah.edu>
Date: Tue, 7 Mar 89 15:55:10 MST
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>, Eric Benson <eb@lucid.com>,
pierson@mist.encore.com, cl-compiler@sail.stanford.edu
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Tue, 7 Mar 89 17:18 EST
> Date: Tue, 7 Mar 89 17:18 EST
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> It makes me wonder if
> perhaps we shouldn't retreat to a minimalist position where PROGN is
> the only special case.
>
> Do we really have to rehearse all the arguments as to why that won't work
> once again?
I'm not aware that such arguments have ever been coherently stated. I
just went through all my back mail on this subject and couldn't find
anything on it from you or from anyone else.
Perhaps we need to be reminded that the minimalist position is
actually the status quo -- PROGN is the only special case mentioned by
CLtL. COMPILER-LET got added to our list because it is also treated
as a special case by implementations derived from the MIT Lisp
Machine. MACROLET and SYMBOL-MACROLET got added because some people
thought it would be generally useful.
I question whether the problem with LOCALLY justifies trying to come
up with a model of what toplevelness is that is radically different
than what is specified in CLtL. The example you cited in your
original message was putting a DEFUN form inside of a LOCALLY. That
would still be legitimate Common Lisp regardless of whether or not the
DEFUN is considered to be at top-level, and since we do not require
DEFUN to do any compile-time evaluation, what are you losing?
> I'm sorry I flamed so much in this message, but this is the type of response
> that makes me wonder if the whole X3J13 effort is nothing but an exercise
> in futility.
I know how you feel; I'm also getting very sick and tired of this
issue. We've been going around in circles on it for a year now and we
don't seem any closer to any real understanding or consensus.
-Sandra
-------
∂07-Mar-89 1546 Common-Lisp-Object-System-mailer Re: remote environments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Mar 89 15:46:17 PST
Received: from Semillon.ms by ArpaGateway.ms ; 07 MAR 89 15:39:49 PST
Date: 7 Mar 89 15:39 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: remote environments
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message
of Mon, 6 Mar 89 21:37 EST
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: David N Gray <Gray@DSG.csc.ti.com>,
Common-Lisp-Object-System@SAIL.Stanford.edu, CL-Compiler@SAIL.Stanford.edu
Message-ID: <890307-153949-8334@Xerox>
I agree with Gray and you. There is further internal evidence in your
message that we will have to allow instances of classes defined in the file
being compiled to be instantiated. You answer for:
DEFINE-METHOD-COMBINATION
* Used in a later DEFGENERIC?
- Callable at compile-time?
Moon: I believe this should be yes to both, although if I'm not
mistaken Flavors does not allow it. I think that's a bad design
choice in Flavors.
I agree. And the metaobject protocol specifies that this
definition can define a new method-combination class.
An instance of this class is used in the DEFGENERIC to effect the
method combination. This implies an ability to instantiate
a newly defined class at compile time to implement this capability.
Another reason to answer the instntiation question YES.
∂07-Mar-89 1744 CL-Compiler-mailer A (new) (old) definition of "top-level"
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 7 Mar 89 17:44:04 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA24207; Tue, 7 Mar 89 18:41:46 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA08237; Tue, 7 Mar 89 18:41:36 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903080141.AA08237@defun.utah.edu>
Date: Tue, 7 Mar 89 18:41:35 MST
Subject: A (new) (old) definition of "top-level"
To: cl-compiler@sail.stanford.edu
Cc: moon@stony-brook.scrc.symbolics.com
I've spent the past few hours digging around through the literature to
try to get a historical perspective on the use of the term
"top-level". Believe it or not, I've actually found a definition of
the term, from the 1st edition of Winston & Horn's LISP book:
A function is said to be defined or used in the top-level environment
if its definition or use is directly demanded by a user, rather
than indirectly by way of the evaluation of one or more other functions.
Historically, it appears that the term "top-level" was first used in
the context of "top-level READ-EVAL-PRINT loop", a context which also
has an implication of direct evaluation. For example, the manuals for
Stanford Lisp 1.6 (PDP-10) and UT Lisp (CDC-6000) talk about EVAL
being the default "top-level function", and use "top-level expression"
to mean an expression read in and evaluated by the top-level loop.
For example, here's what the UT Lisp manual has to say:
A LISP program is usually composed of a simple sequence of LISP
expressions, or forms, to be evaluated. [...] Program execution is
handled by the function EVAL, the usual "top-level function". EVAL is
called to evaluate successive input expressions in the order they
appear.
Likewise, the Franz Lisp manual uses "top-level" as a noun to mean
"top-level loop".
So how does this notion of top-level-ness fit in to Common Lisp? I
think we have to consider the traditional implementation of a Lisp
interpreter as a recursive procedure. What the Winston & Horn
definition implies is that a top-level form is a form that is seen by
the outermost explicit call to EVAL, and that any recursive calls to
evaluate subforms are not top-level.
In Common Lisp, note that the EVAL function itself cannot be defined
recursively because it doesn't take an environment object. (I hope
that's obvious without me needing to present a proof.) Let's suppose
EVAL is implemented by calling a recursive internal function, passing
it the form and a null lexical environment object. Then, any form
that EVAL itself receives as an argument is a top-level form, but any
subforms which are seen only by the internal function are not
top-level.
This definition doesn't have anything to do with what kinds of things
are in the lexical environment or whether or not they can be
determined in advance. It does fit in with something we've discussed
before, namely that top-level-ness implies evaluation in a null
lexical environment.
Now to to extend this to file compilation. LOADing a source file is
defined as reading and evaluating forms from the file. Since there is
direct evaluation going on, each form that is read from the file is
top-level. This notion applies just as well to COMPILE-FILE, which
must arrange for the loader to "evaluate" or "execute" each of the
top-level forms.
Finally, we have implicitly accepted the idea that macroexpansion by
the compiler must preserve semantics. That implies that
macroexpansion should not have any effect on top-level-ness. Thinking
about our simple compiler model that doesn't do much besides walk the
code to expand all macros and print out the results, if it is allowed
to turn the bodies of COMPILER-LETs, MACROLETs, and SYMBOL-MACROLETs
into PROGNs, then that would be an argument for saying that those
three special forms should be treated the same as PROGN as far as
top-level-ness goes. However, that rationale wouldn't cover
constructs like LOCALLY and LABELS (as Moon suggests) unless we modify
our compiler model.
This way of thinking about top-level-ness makes sense to me. How
about the rest of you?
-Sandra
-------
∂07-Mar-89 1825 CL-Compiler-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 7 Mar 89 18:24:55 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 552620; Tue 7-Mar-89 21:21:40 EST
Date: Tue, 7 Mar 89 21:21 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Potential issue: MACRO-SPECIAL-FORMS
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
cc: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, cl-compiler@sail.stanford.edu,
cl-cleanup@sail.stanford.edu
In-Reply-To: <3256.8902271723@subnode.aiai.ed.ac.uk>
Message-ID: <19890308022127.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Just a comment: I really believe that CLtL's goal of minimizing the
number of special forms that a code-analyzer has to understand by
relying on macros is misguided and non-achievable. Consider Sandra's
experience, which I believe other people have had in other
implementations, with something that CLtL says is a macro, but the
compiler does a better job of compiling the macro call than of compiling
the nominally equivalent macro expansion. Just consider how well CLtL's
goal has been achieved in practice: not at all.
I think Common Lisp would do better to define everything that "everybody
knows" is a special form to be a special form; this would include all
the control structures, but not SETF. My claim is that this would not
make it any more difficult to do code analysis, because in practice code
analyzers have to know about most of those forms anyway, and because the
extra work to make a typical code analyzer know about a typical special
form, even something as complicated as DO, is usually fairly small,
certainly less work than figuring out what weird macro expansions all
the implementations in the world will use for DO and making sure the
code analyzer works right for each of them. This is even more true when
you use a pattern-driven code analyzer, such as the one I wrote in 1983
and have given to everyone who asked, or the one in Interlisp
MasterScope (which was my model, although I didn't look at the detailed
code).
An alternative position that I'd consider would be to mandate the exact
macro expansion of a number of these forms, not allowing implementations
to deviate. Essentially that would be moving these things into a
portable library. I suppose that might devolve into endles nitpicking
discussions that we don't need.
∂08-Mar-89 1145 CL-Compiler-mailer issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 8 Mar 89 11:44:11 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA19010; Wed, 8 Mar 89 12:42:02 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA08790; Wed, 8 Mar 89 12:41:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903081941.AA08790@defun.utah.edu>
Date: Wed, 8 Mar 89 12:41:58 MST
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
To: cl-compiler@sail.stanford.edu
Here's the latest draft. The major change in content here is that I
have removed the item that dealt with CLOS requirements, and added a
requirement to make the handling of type specifiers defined with
DEFCLASS parallel that for DEFTYPE and DEFSTRUCT. I have also tried
to generally clean up the wording of the writeup in accordance with
various suggestions I've received, from Kathy Chapman and others.
Please let me know if there are additional changes you'd like to see.
Forum: Compiler
Issue: COMPILE-ENVIRONMENT-CONSISTENCY
References: CLtL p. 68-69, 143, 321
RAM's "Compiler Cleanup Proposal #3"
Category: CLARIFICATION
Edit History: V1, 2 Sep 1988, Sandra Loosemore (initial draft)
V2, 9 Sep 1988, Sandra Loosemore (incorporate suggestions)
V3, 26 Oct 1988, Sandra Loosemore (add suggestion from Benson)
V4, 08 Mar 1989, Sandra Loosemore (wording changes)
Problem Description:
CLtL does not clearly specify what aspects of the compiletime
environment the compiler (or other preprocessor) may "wire in" to code
being compiled. At what time (compiletime or runtime) are certain
kinds of definitions "captured"? What happens if these definitions
are not consistent at both compile and run times?
Proposal COMPILE-ENVIRONMENT-CONSISTENCY:CLARIFY:
The process of compilation causes certain kinds of information present
in the compiletime environment to be captured and incorporated into
the resulting compiled code. Other kinds of information may not be
captured until the compiled code is actually run.
Specifically:
(1) The following information *must* be present in the compiletime
environment for the program to be compiled correctly. This
information need not also be present in the runtime environment.
(a) In conforming code, macros referenced in the code being compiled
must have been previously defined in the compiletime environment.
The compiler must treat any form that is a list beginning with
a symbol that does not name a macro or special form as a function
call. (This implies that SETF methods must also be available at
compiletime.)
(b) In conforming code, variables that are intended to be bound
specially must be declared SPECIAL in the compiletime environment
before any bindings of that variable are processed by the compiler.
The compiler must treat any binding of an undeclared variable as a
lexical binding.
(2) The compiler *may* incorporate the following kinds of information
into the code it produces, if the information is present in the
compiletime environment and is referenced within the code being
compiled. Except where some other behavior is explicitly stated, when
the compiletime and runtime definitions are different, it is
unspecified which will prevail within the compiled code. In all
cases, the absence of the information at compiletime is not an error,
but its presence may enable the compiler to generate more efficient
code.
(a) The compiler may assume that functions that are defined and
declared INLINE in the compiletime environment will retain the
same definitions at runtime.
(b) The compiler may assume that, within a named function, a
recursive call to a function of the same name refers to the
same function, unless that function has been declared NOTINLINE.
(c) COMPILE-FILE may assume that, in the absence of NOTINLINE
declarations, a call within the file being compiled to a named
function which is defined in that file refers to that function.
(This permits "block compilation" of files.) The behavior of
the program is unspecified if functions are redefined individually
at runtime.
(d) The compiler may assume that the signature (or "contract") of
all built-in Common Lisp functions will not change. In addition,
the compiler may treat all built-in Common Lisp functions as if
they had been proclaimed INLINE.
(e) The compiler may assume that the signature (or "contract") of
functions with FTYPE information available will not change. (See
issue FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS.)
(f) The compiler may "wire in" the values of symbolic constants
that have been defined with DEFCONSTANT in the compiletime
environment.
(g) The compiler can assume that type definitions made with DEFTYPE
or DEFSTRUCT in the compiletime environment will retain the same
definition in the runtime environment. It may also assume that
a class defined by DEFCLASS in the compiletime environment will
be defined in the runtime environment in such a way as to have
the same superclasses and metaclass. This implies that
subtype/supertype relationships of type specifiers will not
change between compiletime and runtime. (Note that it is not
an error for an unknown type to appear in a declaration at
compiletime, although it is reasonable for the compiler to
emit a warning in such a case.)
(h) The compiler may assume that if type declarations are present
in the compiletime environment, the corresponding variables and
functions present in the runtime environment will actually be of
those types; otherwise, the runtime behavior of the program is
undefined.
(3) The compiler *must not* make any additional assumptions about
consistency between the compiletime and runtime environments. In
particular:
(a) The compiler may not assume that functions that are defined
in the compiletime environment will retain the either the
same definition or the same signature at runtime, except
in situations (2a) through (2e) above. It is, however,
permissible for the compiler to emit warning messages when
compiling calls to functions that are defined in the compiletime
environment, but where the wrong number or type of arguments
are supplied.
(b) The compiler may not signal an error if it sees a call to a
function that is not defined at compiletime, since that function
may be provided at runtime. Again, it is permissible for the
compiler to emit a warning in these situations.
Rationale:
This proposal generally reflects current practice.
Current Practice:
There don't seem to be any compilers around that do not implement the
provisions of item (1).
For item (2), most compilers (including Lucid) optimize self-recursive
calls by default. Most compilers also opencode data structure
accessors (such as CAR) at some level of optimization, and some code
much more complicated built-in functions inline as well. VaxLisp, for
example, normally compiles MEMBER inline. The Lucid compiler makes
use of type declarations to perform generic-to-specific
transformations on many arithmetic and sequence functions, which is
also a form of inlining. KCL performs block compilation by default,
and Lucid does so under certain conditions.
Cost to implementors:
Unknown, but probably minor.
Cost to users:
Since most implementations appear to be largely in conformance with the
proposal, users should notice little difference.
Benefits:
The presence of a definite specification of what may happen when will
help users structure their programs so they will compile correctly in
all Common Lisp implementations.
Discussion:
Most of the discussion on this issue has been centered on the
terminology describing error situations for item (2). In most cases
where there is an inconsistency between compile-time and run-time, the
results will be unpredictable but harmless. The major exception is
violation of type declarations, which is a "crash-and-burn" error in
many implementations.
There has also been some concern raised that item (3) would prohibit
such things as a cross-compiler that produces standalone programs in
an environment that disallows redefinition of functions. The intent
of this proposal is not to prohibit a compiler from having a magic
switch that imposes additional restrictions on the programs it
compiles, but such a compiler would not be a compiler for Common Lisp.
Several people have expressed reservations about items 2b and 2c, saying
that self-tail-recursion optimization and block compilation should not
be the default behavior of the compiler. Gail Zacharias responds:
This item [2c] has nothing to do with whether anybody does it by
default. The question is whether an end user can take a Common Lisp
program whose internals he's not familiar with, block-compile it, and
be guaranteed that it will continue to function correctly. This item
says that yes, a correct CL program must explicitly indicate what
functions in the source it will redefine at runtime. I don't think
this places such a great burden on the programmer. Without this
provision, only somebody intimately familiar with a program could know
whether it can be safely block-compiled, making block-compilation
useless in the context of portable CL programs.
This thing about "block compilation shouldn't be the default" seems to
come up every time this item is discussed. That's an environment
question and is not addressed by the proposal. The proposal simply
says that block compilation should be legal.
-------
∂08-Mar-89 1401 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 8 Mar 89 14:01:17 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA24990; Wed, 8 Mar 89 14:59:09 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA08869; Wed, 8 Mar 89 14:59:06 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903082159.AA08869@defun.utah.edu>
Date: Wed, 8 Mar 89 14:59:05 MST
Subject: issue COMPILER-LET-CONFUSION, version 6
To: cl-compiler@sail.stanford.edu
This is another one of the issues I had marked as being in need of
major revisions. Kent and I think that this writeup is ready to go.
If anybody else has something to add to the discussion section, let me
know ASAP.
Issue: COMPILER-LET-CONFUSION
Forum: Compiler
References: CLtL p. 112
Category: CHANGE
Edit History: V1, 27 Sep 1988, Sandra Loosemore (initial version)
V2, 04 Oct 1988, Sandra Loosemore (add another example)
V3, 31 Oct 1988, Sandra Loosemore (only proposal ELIMINATE)
V4, 08 Jan 1989, Kent M. Pitman (new alternative)
V5, 09 Jan 1989, Sandra Loosemore (discussion)
V6, 08 Mar 1989, Sandra Loosemore (general updating)
Problem Description:
The description of the COMPILER-LET special form in CLtL is confusing
to many people. There are no examples provided to make it clear how it
is supposed to be used. The only description which is offered is overly
concrete, which have led to confusion about the intent of COMPILER-LET,
and about its implementability.
The intent of COMPILER-LET was to permit information to be communicated
between macros by use of dynamic variables at macroexpansion time.
It was not necessary to the intended uses of COMPILER-LET that such
variables ever be bound at execution time.
Unfortunately, probably because some implementations did not primitively
support COMPILER-LET at the time CLtL was written, an exception was
permitted to make COMPILER-LET `more or less work' in interpreters:
the COMPILER-LET variables were permitted to be bound at execution time.
The problem was further compounded by the fact that CLtL presented this
exception as part of COMPILER-LET's contract rather than as an
implementation note, and by the fact that no examples of actually using
COMPILER-LET correctly are provided.
Subtle bugs can be introduced because of the different handling of the
variable bindings in the interpreter and the compiler. In compiled
code, the bindings are only lexically visible during the expansion of
macros at compile time, while in interpreted code the bindings have
dynamic scope and may also be seen during ordinary evaluation if
evaluation and macroexpansion happen concurrently.
Further compatibility problems can result from the value forms being
evaluated in a null lexical environment in the compiler and the ordinary
lexical environment in the interpreter.
Background and Analysis:
It should be clear up front that COMPILER-LET is not computationally
essential. Most (if not all) uses of it can be rewritten using MACROLET
or SYMBOL-MACROLET.
A typical use of COMPILER-LET might be:
(defvar *local-type-declarations* '())
(defmacro local-type-declare (declarations &body forms)
`(compiler-let ((*local-type-declarations*
(append ',declarations *local-type-declarations*)))
,@forms))
(defmacro typed-var (var)
(let ((type (assoc var *local-type-declarations*)))
(if type `(the ,(cadr type) ,var) var)))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
The same thing could be accomplished using MACROLET:
(defmacro local-type-declare (declarations &body forms)
(local-type-declare-aux declarations forms))
(defmacro typed-var (var) var)
(eval-when (eval compile load)
(defun local-type-declare-aux (declarations forms)
`(macrolet ((typed-var (var)
(let ((type (assoc var ',declarations)))
(if type `(the ,(cadr type) ,var) var)))
(local-type-declare (new-declarations &body new-forms)
(local-type-declare-aux
(append new-declarations ',declarations)
new-forms)))
,@forms)))
A further alternative would be to use SYMBOL-MACROLET (this particular
implementation assumes that issue DEFINING-MACROS-NON-TOP-LEVEL passes):
(let ((temp (gensym)))
(defmacro local-type-declare (declarations &body forms &environment env)
`(symbol-macrolet ((,temp ',(append declarations
(symbol-macro-value temp env))))
,@forms))
(defmacro typed-var (var &environment env)
(let ((type (assoc var (symbol-macro-value temp env))))
(if type `(the ,(cadr type) ,var) var)))
)
(defun symbol-macro-value (symbol env &optional default)
(multiple-value-bind (expansion macro-p) (eval (macroexpand symbol env))
(if macro-p expansion default)))
Opinion is divided as to which is more understandable. Some
people find the COMPILER-LET idiom more understandable, while others
find it just as natural to use MACROLET or SYMBOL-MACROLET.
The issues are these:
- Is it possible to implement COMPILER-LET in a usefully consistent
way in all implementations?
- Are the benefits of providing a useful and compatible implementation
of COMPILER-LET worth any associated cost?
Two proposals are presented below:
- Option REPAIR argues that COMPILER-LET provides interesting
functionality that can be implemented in a manner that is usefully
consistent across implementations, and that the associated cost
is low enough for it to be worthwhile to do so.
- Option ELIMINATE argues that COMPILER-LET complicates the language
and that providing this construct is not worth the associated
implementation cost.
Proposal (COMPILER-LET-CONFUSION:REPAIR):
Strike the existing definition of COMPILER-LET. Redefine it as follows:
COMPILER-LET [Special form]
COMPILER-LET is similar to LET, but it always makes special
bindings and makes those bindings visible only during
macroexpansion of forms in the body, not during the runtime
execution of those forms.
The intent is that some macros might macroexpand into calls to
COMPILER-LET in which the body would the contain references to
macros which access the variables in the COMPILER-LET.
The initial value forms of the bindings, if any, are always
evaluated in a null lexical context, regardless of whether the
COMPILER-LET expression is being interpreted or compiled.
The initial value forms of the bindings, if any, are evaluated in
a dynamic context where the bindings of any lexically enclosing
COMPILER-LET are visible, and where dynamic execution-time
environment may or may not be visible.
Implementation Note: Permitting the execution-time dynamic
environment to be visible when initializing COMPILER-LET variables
is a concession to some interpreters which may have to do this in
order to keep the cost down. Where feasible, implementors should
try not to make the runtime environment visible.
Rationale:
This gives a consistent description of COMPILER-LET which separates
issues of intent from those of implementation in a way that makes it
possible for portable code to make serious use of it, and which does
not force gratuitous incompatibilities between interpreters and
compilers.
This description of COMPILER-LET can be implemented without undue
cost by all implementations. See "Cost to Implementors" for details.
Cost to Implementors:
Modest, but nontrivial in some implementations.
In compiled code, and in interpreters doing a one-time semantic
prepass, it should be fairly easy for COMPILER-LET to cause the
variables to get bound (using PROGV) during semantic analysis.
In interpreters which do not do a semantic-prepass, it is necessary
to fully macroexpand the body. Assuming the presence of a
SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
could look like:
(DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
(SETQ BINDINGS ;; Assure no non-atom bindings
(MAPCAR #'(LAMBDA (BINDING)
(IF (ATOM BINDING) (LIST BINDING) BINDING))
BINDINGS))
(PROGV (MAPCAR #'CAR BINDINGS)
(MAPCAR #'CDR BINDINGS)
(SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))
This reduces the problem of writing a program capable of doing a
full macroexpansion. Many systems already have such a facility.
Pitman wrote such a facility in Cloe Runtime in order support
SYMBOL-MACROLET (before it was christened a special form); it was
about 750 lines of relatively straightforward, well-commented code.
Cost to Users:
Code currently depending on this feature is either non-existent or
already not portable (due to wide variation in implementation
strategy for COMPILER-LET).
Most users will probably be happy for any interpretation which offers
them a future shot at portability.
Some users have indicated they dislike interpreters which do a semantic
prepass, because they like to be able to dynamically redefine macros
while debugging.
Proposal (COMPILER-LET-CONFUSION:ELIMINATE):
Remove COMPILER-LET from the language.
Rationale:
Some people think that having one less special form would simplify the
language. The revised COMPILER-LET semantics, which require
COMPILER-LET to make special bindings which are only lexically visible
within its body, are not shared by any other feature in the language,
and require a fairly complex implementation technique. There are
other constructs which are strictly lexical that can be readily used
to solve the same kinds of problems that COMPILER-LET is intended to
be used for.
Cost to Implementors:
Minimal. Implementations could continue to support COMPILER-LET as
an extension.
Cost to Users:
People who use COMPILER-LET would have to rewrite their programs to use
some other construct. As discussed above, most uses of COMPILER-LET
for communication between macros can be handled using MACROLET or
SYMBOL-MACROLET, though some perspicuity may be lost in the process.
Current Practice:
Some implementations have implemented the description in CLtL.
Users of those implementations (quite reasonably) can't figure how to
use COMPILER-LET and so don't use it much.
Some implementations (the ones from which COMPILER-LET originally came)
continue to use their pre-CLtL semantics. These semantics are useful, though
incompatible with CLtL (which they largely consider to simply be in error).
Users of those implementations probably use COMPILER-LET somewhat more
often since it has an intelligible behavior, but their code is not portable
since it relies on behaviors which are either contrary to or not guaranteed
by CLtL.
Benefits:
Either way, a potential area of incompatibility between compiled and
interpreted code would be eliminated.
Either way, a potential area of portability trouble would be very
drastically reduced (in the case of the REPAIR option) or eliminated
(in the case of the ELIMINATE option).
Discussion:
Pitman strongly favors COMPILER-LET-CONFUSION:REPAIR. He argues
against the idea of using MACROLET instead of COMPILER-LET, saying:
This is a little misleading because it's like saying you can
do without LET given that you have FLET. You can, but you lose some things
in the process:
Just as rewriting a LET using FLET might slow your computation, so too
a rewrite of COMPILER-LET using MACROLET might slow things down. However,
compilation speed is generally not weighted as heavily as execution speed
by many people, so the loss of speed here may not be as important.
Just as rewriting a LET using FLET might obscure the simplicity of your
intent, so too rewriting COMPILER-LET using MACROLET might obscure your
intent. You'd probably get used to recognizing idioms if you used it often
enough. Certainly this would be true if you didn't have LET. However,
COMPILER-LET is used less often, so not having it would mean that the
code you wrote instead would be much harder to read because people
wouldn't have the necessary familiarity with the idioms involved and so
wouldn't always understand them.
Sandra Loosemore responds:
The argument that using MACROLET is more inefficient than COMPILER-LET
is questionable. Both of the suggested implementation techniques for
COMPILER-LET involve considerable overhead.
If COMPILER-LET were not part of the language, people wouldn't think in
terms of rewriting COMPILER-LETs as MACROLETs; instead, they'd think of
how to use MACROLET in the first place to solve their problems. This
is what people who now use implementations with broken COMPILER-LETs
already do. Since MACROLET is now used much more frequently than
COMPILER-LET, that argues that people are much more familiar with
MACROLET idioms than COMPILER-LET idioms.
Also, note that the intent of the revised COMPILER-LET definition is
to make the binding only lexically visible within the body. Using
special binding for this purpose is troublesome. Both the MACROLET
and SYMBOL-MACROLET solutions are completely lexical and avoid all
the problems associated with special binding.
-------
∂08-Mar-89 1416 CL-Compiler-mailer issue COMPILER-LET-CONFUSION, version 6
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Mar 89 14:16:17 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 553273; Wed 8-Mar-89 17:13:14 EST
Date: Wed, 8 Mar 89 17:13 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-LET-CONFUSION, version 6
To: sandra%defun@cs.utah.edu
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8903082159.AA08869@defun.utah.edu>
Message-ID: <890308171306.8.KMP@BOBOLINK.SCRC.Symbolics.COM>
Sigh. I blew it slightly when I suggested that last minute fix to the
SYMBOL-MACROLET rewrite. You have
(defun symbol-macro-value (symbol env &optional default)
(multiple-value-bind (expansion macro-p) (eval (macroexpand symbol env))
(if macro-p expansion default)))
but it should have been
(defun symbol-macro-value (symbol env &optional default)
(multiple-value-bind (expansion macro-p) (macroexpand symbol env)
(if macro-p (eval expansion) default)))
Sorry about that.
∂08-Mar-89 1708 CL-Compiler-mailer A (new) (old) definition of "top-level"
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Mar 89 17:08:36 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 553434; Wed 8-Mar-89 20:05:41 EST
Date: Wed, 8 Mar 89 20:05 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: A (new) (old) definition of "top-level"
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: cl-compiler@sail.stanford.edu
In-Reply-To: <8903080141.AA08237@defun.utah.edu>
Message-ID: <19890309010519.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 7 Mar 89 18:41:35 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
I've spent the past few hours digging around through the literature to
try to get a historical perspective on the use of the term
"top-level". Believe it or not, I've actually found a definition of
the term, from the 1st edition of Winston & Horn's LISP book:
A function is said to be defined or used in the top-level environment
if its definition or use is directly demanded by a user, rather
than indirectly by way of the evaluation of one or more other functions.
I think this is an unrelated use of the same word and doesn't tell
us anything.
Now to to extend this to file compilation. LOADing a source file is
defined as reading and evaluating forms from the file. Since there is
direct evaluation going on, each form that is read from the file is
top-level. This notion applies just as well to COMPILE-FILE, which
must arrange for the loader to "evaluate" or "execute" each of the
top-level forms.
Finally, we have implicitly accepted the idea that macroexpansion by
the compiler must preserve semantics. That implies that
macroexpansion should not have any effect on top-level-ness. Thinking
about our simple compiler model that doesn't do much besides walk the
code to expand all macros and print out the results, if it is allowed
to turn the bodies of COMPILER-LETs, MACROLETs, and SYMBOL-MACROLETs
into PROGNs, then that would be an argument for saying that those
three special forms should be treated the same as PROGN as far as
top-level-ness goes. However, that rationale wouldn't cover
constructs like LOCALLY and LABELS (as Moon suggests) unless we modify
our compiler model.
This way of thinking about top-level-ness makes sense to me. How
about the rest of you?
I think this makes sense, but all it says is that a top-level form is
one that is not inside another form.
We need to go back and ask why the compiler has to have a concept of
top-level form in the first place. (Surely it would be better if we
could just jettison the concept entirely.) I think the concept exists
only because in compile-file defmacro as a top-level form does something
rather different from defmacro as a non-top-level form. There are a few
others (deftype, defsetf) in the same category. Then the important
thing about top-level forms is not whether they are enclosed in
parentheses, but whether they can get this special compiler treatment of
defmacro. I could now repeat what I said yesterday but I'll spare you.
I think it fits very well with your simple compiler model, though.
∂08-Mar-89 1719 CL-Compiler-mailer Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Mar 89 17:19:21 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 553441; Wed 8-Mar-89 20:16:02 EST
Date: Wed, 8 Mar 89 20:15 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: Eric Benson <eb@lucid.com>, pierson@mist.encore.com, cl-compiler@sail.stanford.edu
In-Reply-To: <8903072255.AA08178@defun.utah.edu>
Message-ID: <19890309011538.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 7 Mar 89 15:55:10 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Date: Tue, 7 Mar 89 17:18 EST
> From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>
> It makes me wonder if
> perhaps we shouldn't retreat to a minimalist position where PROGN is
> the only special case.
>
> Do we really have to rehearse all the arguments as to why that won't work
> once again?
I'm not aware that such arguments have ever been coherently stated. I
just went through all my back mail on this subject and couldn't find
anything on it from you or from anyone else.
I think you're right that it would work to not make locally, macrolet,
labels, and so forth when used at top-level treat their bodies as
top-level. It would be less esthetic, but it wouldn't fail to work.
I was confused on that point. What I was thinking of was eval-when;
CLtL p.70 seems quite clear that when an eval-when is processed
as a top-level form, and the situation LOAD is specified, the forms
in the body are also processed as top-level forms. It doesn't use
the word "top-level" but from the context that's what "process" means.
I also really believe that it will not work to change this so that
the body of an eval-when is not top-level.
Perhaps we need to be reminded that the minimalist position is
actually the status quo -- PROGN is the only special case mentioned by
CLtL.
I'd claim PROGN and EVAL-WHEN. I agree that CLtL doesn't require anything
else.
I question whether the problem with LOCALLY justifies trying to come
up with a model of what toplevelness is that is radically different
than what is specified in CLtL.
No, what justifies coming up with a model is that noone can understand
the description in CLtL, including I think its authors.
∂09-Mar-89 0832 CL-Compiler-mailer Re: issue COMPILER-LET-CONFUSION, version 6
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 9 Mar 89 08:30:56 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa07305; 9 Mar 89 15:31 GMT
Date: Thu, 9 Mar 89 16:00:42 GMT
Message-Id: <29341.8903091600@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: issue COMPILER-LET-CONFUSION, version 6
To: sandra (Sandra J Loosemore) <@cs.utah.edu:sandra@defun>,
cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Wed, 8 Mar 89 14:59:05 MST
> Problem Description:
>
> The description of the COMPILER-LET special form in CLtL is confusing
> to many people. There are no examples provided to make it clear how it
> is supposed to be used. The only description which is offered is overly
> concrete, which have led to confusion about the intent of COMPILER-LET,
↑↑↑↑ has
> and about its implementability.
>
> The intent of COMPILER-LET was to permit information to be communicated
> between macros by use of dynamic variables at macroexpansion time.
> It was not necessary to the intended uses of COMPILER-LET that such
> variables ever be bound at execution time.
>
> Unfortunately, probably because some implementations did not primitively
> support COMPILER-LET at the time CLtL was written, an exception was
> permitted to make COMPILER-LET `more or less work' in interpreters:
Is it really "interpreters" (verses some unspecified other thing), or
macroexpansion time verses executiontime?
> the COMPILER-LET variables were permitted to be bound at execution time.
> The problem was further compounded by the fact that CLtL presented this
> exception as part of COMPILER-LET's contract rather than as an
> implementation note, and by the fact that no examples of actually using
> COMPILER-LET correctly are provided.
>
> Subtle bugs can be introduced because of the different handling of the
> variable bindings in the interpreter and the compiler. In compiled
> code, the bindings are only lexically visible during the expansion of
> macros at compile time, while in interpreted code the bindings have
> dynamic scope and may also be seen during ordinary evaluation if
> evaluation and macroexpansion happen concurrently.
Concurrently?
> Further compatibility problems can result from the value forms being
> evaluated in a null lexical environment in the compiler and the ordinary
> lexical environment in the interpreter.
There's nothing here about occasions such as
(compiler-let ((*v* 1))
#'(lambda () (m)))
where M is a macro that refers to *V*, but the lambda-expr isn't
macroexpanded until it's finally called, and so parhpas after the
dynamic extent of the *V* binding has ended. Isn't this part of
the "problem"?
> Background and Analysis:
> [...]
> Opinion is divided as to which is more understandable. Some
> people find the COMPILER-LET idiom more understandable, while others
> find it just as natural to use MACROLET or SYMBOL-MACROLET.
There's also the problem that the COMPILER-LET may not work, due
to the extent problem noted above.
> Proposal (COMPILER-LET-CONFUSION:REPAIR):
> [...]
> In interpreters which do not do a semantic-prepass, it is necessary
> to fully macroexpand the body. Assuming the presence of a
> SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
> could look like:
> (DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
> (SETQ BINDINGS ;; Assure no non-atom bindings
> (MAPCAR #'(LAMBDA (BINDING)
> (IF (ATOM BINDING) (LIST BINDING) BINDING))
> BINDINGS))
> (PROGV (MAPCAR #'CAR BINDINGS)
> (MAPCAR #'CDR BINDINGS)
> (SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))
> This reduces the problem of writing a program capable of doing a
> full macroexpansion. Many systems already have such a facility.
> Pitman wrote such a facility in Cloe Runtime in order support
> SYMBOL-MACROLET (before it was christened a special form); it was
> about 750 lines of relatively straightforward, well-commented code.
The need for a prepass (why "semantic prepass"?) isn't explained,
and there's nothing in the problem description (about the extent issue,
say) that indicates there's a problem the prepass solves.
> Cost to Users:
>
> Code currently depending on this feature is either non-existent or
> already not portable (due to wide variation in implementation
> strategy for COMPILER-LET).
>
> Most users will probably be happy for any interpretation which offers
> them a future shot at portability.
>
> Some users have indicated they dislike interpreters which do a semantic
> prepass, because they like to be able to dynamically redefine macros
> while debugging.
Can macros be expanded to something that records the COMPILER-LET
nevironment so that they could be correctly re-expanded later? For
example, suppose macro expansions were cached (in a hash table, say)
and the original code left in place. Then, if the macro is redefined,
the expansion is recomputed. The C-LET environment could be saved
along with the expansion. Would that work?
> Proposal (COMPILER-LET-CONFUSION:ELIMINATE):
>
> Remove COMPILER-LET from the language.
>
> Rationale:
>
> Some people think that having one less special form would simplify the
> language. The revised COMPILER-LET semantics, which require
> COMPILER-LET to make special bindings which are only lexically visible
"only lexically visible" isn't quite right. It sounds like you're
saying they have lexical scope, but they don't because they're visible
to macro functions. So I think they have indefinite scope and dynamic
extent, like all special variables, but the extent is macroexpansion
time rather than execution time.
> within its body, are not shared by any other feature in the language,
> and require a fairly complex implementation technique. There are
> other constructs which are strictly lexical that can be readily used
> to solve the same kinds of problems that COMPILER-LET is intended to
> be used for.
> [...]
> Current Practice:
>
> Some implementations have implemented the description in CLtL.
> Users of those implementations (quite reasonably) can't figure how to
> use COMPILER-LET and so don't use it much.
>
> Some implementations (the ones from which COMPILER-LET originally came)
> continue to use their pre-CLtL semantics. These semantics are useful, though
> incompatible with CLtL (which they largely consider to simply be in error).
I always find this mysterious because I don't know what the "pre CLtL"
semantics was (if it's diffeerent).
> Users of those implementations probably use COMPILER-LET somewhat more
> often since it has an intelligible behavior, but their code is not portable
> since it relies on behaviors which are either contrary to or not guaranteed
> by CLtL.
> [...]
-- Jeff
∂09-Mar-89 1102 CL-Compiler-mailer Issue MACRO-ENVIRONMENT-EXTENT
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 11:02:43 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 553814; Thu 9-Mar-89 13:59:24 EST
Date: Thu, 9 Mar 89 13:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue MACRO-ENVIRONMENT-EXTENT
To: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>, sandra%defun@CS.UTAH.EDU
cc: cl-compiler@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <12472024104.5.IIM@ECLA.USC.EDU>
Message-ID: <19890309185905.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Sun 19 Feb 89 15:54:36-PST
From: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>
The extent of macro environment objects is related to EVAL-WHEN because macro
expanders may wish to return forms which contain environments as quoted
constants.
I am convinced that this should be ruled out, and that CLOS made a mistake
here. (Incidentally the part of CLOS that says this is in chapter 3, the
accepted part of CLOS does not say anything about the expansion of the
macros is.)
....
Requiring environments to have indefinite extent has
problems for CLOS because at compile-time it wants to create remote metaobjects
and link them into the right places, but then flush those links when the
compilation is over.
This depends on whether you think the environment actually contains the
table that relates names to objects, or just contains a boolean flag
that tells functions such as FIND-CLASS which of two tables to look in.
Under the latter model, nothing about the environment prevents the
COMPILE-FILE table from being reset at any time. This is one reason
why I think the second model is right.
As far as MACRO-ENVIRONMENT-EXTENT itself goes, I am convinced it should
be dynamic extent. I'm also convinced that the decision on this issue
does not affect CLOS.
∂09-Mar-89 1301 Common-Lisp-Object-System-mailer Re: Issue: LOAD-OBJECTS (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:01:40 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554005; Thu 9-Mar-89 15:58:57 EST
Date: Thu, 9 Mar 89 15:58 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: LOAD-OBJECTS (Version 2)
To: David N Gray <Gray@DSG.csc.ti.com>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU, CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <2809731258-5200907@Kelvin>
Message-ID: <19890309205844.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 13 Jan 89 18:54:18 CST
From: David N Gray <Gray@DSG.csc.ti.com>
This looks good. The only thing I have doubts about is:
> The function MAKE-LOAD-FORM-USING-SLOTS can be useful in user-written
> MAKE-LOAD-FORM methods. Its first argument is the object. Its
> optional second argument is a list of the names of the slots to
> preserve; it defaults to all of the local slots.
> MAKE-LOAD-FORM-USING-SLOTS returns forms that construct an equivalent
> object using MAKE-INSTANCE and SETF of SLOT-VALUE for slots with
> values, or SLOT-MAKUNBOUND for slots without values, or using other
> functions of equivalent effect.
Rather than having the second argument default to a list of all instance
slots, it might be better to consider two separate cases:
1. If a second argument is supplied, then MAKE-INSTANCE will be used to
create the object, (using INITIALIZE-INSTANCE to default the slot
values), and then the designated slots will be forced to
have the proper value.
2. Without a second argument, ALLOCATE-INSTANCE will be used to create
the object (without invoking INITIALIZE-INSTANCE or
SHARED-INITIALIZE), and then all the slots will be filled in.
If you are going to specify all of the slot values, then there shouldn't
be a need to compute default values, and it may be undesirable to invoke
INITIALIZE-INSTANCE -- for example, it might complain about missing
required arguments or perform undesired side-effects.
I don't think it's a good idea to have such a large deviation in behavior
based on whether an optional argument is present or not. What if the
argument is present but its value is a list of all the slots?
I personally cannot figure out whether calling INITIALIZE-INSTANCE when
it's not wanted, or failing to call it when it is wanted, would cause
more unexpected behavior. I have to resolve that by keeping it simple
so the programmer can figure it out on his own. So I think it should
always create the object with MAKE-INSTANCE.
> The default MAKE-LOAD-FORM method for STANDARD-OBJECT signals an
> error.
Wouldn't it be permissible to just not have a default method, so that a
"no applicable method" error is signalled?
Agreed.
∂09-Mar-89 1334 CL-Cleanup-mailer issue IN-PACKAGE-FUNCTIONALITY, version 6
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:34:10 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554064; Thu 9-Mar-89 16:31:08 EST
Date: Thu, 9 Mar 89 16:30 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue IN-PACKAGE-FUNCTIONALITY, version 6
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: cl-cleanup@sail.stanford.edu, cl-compiler@sail.stanford.edu
In-Reply-To: <8901310224.AA25846@defun.utah.edu>
Message-ID: <19890309213057.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
IN-PACKAGE-FUNCTIONALITY:NEW-MACRO is fine with me. Typo:
the name of the new macro is misspelled in the example code
in the cost to implementors section.
I don't like the alternate IN-PACKAGE-FUNCTIONALITY:SELECT-ONLY
proposal as well.
∂09-Mar-89 1329 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:29:07 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554052; Thu 9-Mar-89 16:26:35 EST
Date: Thu, 9 Mar 89 16:26 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-OBJECTS (Version 3)
To: CL-Cleanup@sail.stanford.edu, CL-Compiler@sail.stanford.edu, Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19890309212623.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
At Kauai I was asked to keep working on this and come up with a modified
version based on comments received. Here it is. I hope this is ready
for voting so we can clear it out of the way.
Issue: LOAD-OBJECTS
References: none
Related issues: LOAD-TIME-EVAL,
CONSTANT-COMPILABLE-TYPES,
CONSTANT-CIRCULAR-COMPILATION
Category: ADDITION
Forum: Cleanup
Edit history: Version 1, 2-Jan-89, by Moon (for discussion)
Version 2, 13-Jan-89, by Moon (draft updated from discussion)
Version 3, 9-Mar-89, by Moon (changes suggested by discussion)
Problem description:
Common Lisp doesn't provide any way to use an object of a user-defined
type (defined with DEFCLASS or DEFSTRUCT) as a constant in a program
compiled with COMPILE-FILE. The problem is that LOAD has to be able
to "reconstruct" an equivalent object when the compiled-code file is
loaded, but the programmer has no way to tell LOAD how to do that.
Proposal (LOAD-OBJECTS:MAKE-LOAD-FORM):
Define a new generic function named MAKE-LOAD-FORM, which takes one
argument and returns two values. The argument is an object that is
referenced as a constant or as a self-evaluating form in a file being
compiled by COMPILE-FILE. The objective is to enable LOAD to
construct an equivalent object.
The first value, called the "creation form," is a form that, when
evaluated at load time, should return an object that is equivalent to
the argument. The exact meaning of "equivalent" depends on the type
of object and is up to the programmer who defines a method for
MAKE-LOAD-FORM. This is the same type of equivalence discussed
in issue CONSTANT-COMPILABLE-TYPES.
The second value, called the "initialization form," is a form that,
when evaluated at load time, should perform further initialization of
the object. The value returned by the initialization form is ignored.
If the MAKE-LOAD-FORM method returns only one value, the
initialization form is NIL, which has no effect. If the object used
as the argument to MAKE-LOAD-FORM appears as a constant in the
initialization form, at load time it will be replaced by the
equivalent object constructed by the creation form; this is how the
further initialization gains access to the object.
Both the creation form and the initialization form can contain
references to objects of user-defined types (defined precisely below).
However, there must not be any circular dependencies in creation forms.
An example of a circular dependency is when the creation form for the
object X contains a reference to the object Y, and the creation form
for the object Y contains a reference to the object X. A simpler
example would be when the creation form for the object X contains
a reference to X itself. Initialization forms are not subject to
any restriction against circular dependencies, which is the entire
reason that initialization forms exist. See the example of circular
data structures below.
The creation form for an object is always evaluated before the
initialization form for that object. When either the creation form or
the initialization form references other objects of user-defined types
that have not been referenced earlier in the COMPILE-FILE, the
compiler collects all of the creation and initialization forms. Each
initialization form is evaluated as soon as possible after its
creation form, as determined by data flow. If the initialization form
for an object does not reference any other objects of user-defined
types that have not been referenced earlier in the COMPILE-FILE, the
initialization form is evaluated immediately after the creation form.
If a creation or initialization form F references other objects of
user-defined types that have not been referenced earlier in the
COMPILE-FILE, the creation forms for those other objects are evaluated
before F, and the initialization forms for those other objects are
also evaluated before F whenever they do not depend on the object
created or initialized by F. Where the above rules do not uniquely
determine an order of evaluation, which of the possible orders of
evaluation is chosen is unspecified.
While these creation and initialization forms are being evaluated, the
objects are possibly in an uninitialized state, analogous to the state
of an object between the time it has been created by ALLOCATE-INSTANCE
and it has been processed fully by INITIALIZE-INSTANCE. Programmers
writing methods for MAKE-LOAD-FORM must take care in manipulating
objects not to depend on slots that have not yet been initialized.
It is unspecified whether LOAD calls EVAL on the forms or does some
other operation that has an equivalent effect. For example, the
forms might be translated into different but equivalent forms and
then evaluated, they might be compiled and the resulting functions
called by LOAD, or they might be interpreted by a special-purpose
interpreter different from EVAL. All that is required is that the
effect be equivalent to evaluating the forms.
COMPILE-FILE calls MAKE-LOAD-FORM on any object that is referenced as
a constant or as a self-evaluating form, if the object's metaclass is
STANDARD-CLASS, STRUCTURE-CLASS, any user-defined metaclass (not a
subclass of BUILT-IN-CLASS), or any of a possibly-empty
implementation-defined list of other metaclasses. COMPILE-FILE will
only call MAKE-LOAD-FORM once for any given object (compared with EQ)
within a single file.
It is valid for user programs to call MAKE-LOAD-FORM in other
circumstances, providing the argument's metaclass is not BUILT-IN-CLASS
or a subclass of BUILT-IN-CLASS.
Define a new function named MAKE-LOAD-FORM-USING-SLOTS, which takes
one required argument and one optional argument and returns two
values. This can be useful in user-written MAKE-LOAD-FORM methods.
The first argument is the object. The optional second argument is a
list of the names of the slots to preserve; it defaults to all of the
local slots. MAKE-LOAD-FORM-USING-SLOTS returns forms that construct
an equivalent object using MAKE-INSTANCE and SETF of SLOT-VALUE for
slots with values, or SLOT-MAKUNBOUND for slots without values, or
using other functions of equivalent effect.
MAKE-LOAD-FORM-USING-SLOTS returns two values, thus it can deal with
circular structures. MAKE-LOAD-FORM-USING-SLOTS works for any object
of metaclass STANDARD-CLASS or STRUCTURE-CLASS. Whether the result is
useful in an application depends on whether the object's type and slot
contents fully capture the application's idea of the object's state.
MAKE-LOAD-FORM of an object of metaclass STANDARD-CLASS or
STRUCTURE-CLASS for which no user-defined method is applicable signals
an error. It is valid to implement this either by defining default
methods on STANDARD-OBJECT and STRUCTURE-OBJECT that signal an error
or by having no applicable method for those classes.
Examples:
;; Example 1
(defclass my-class ()
((a :initarg :a :reader my-a)
(b :initarg :b :reader my-b)
(c :accessor my-c)))
(defmethod shared-initialize ((self my-class) ignore &rest ignore)
(unless (slot-boundp self 'c)
(setf (my-c self) (some-computation (my-a self) (my-b self)))))
(defmethod make-load-form ((self my-class))
`(make-instance ',(class-name (class-of self))
:a ',(my-a self) :b ',(my-b self)))
In this example, an equivalent instance of my-class is reconstructed
by using the values of two of its slots. The value of the third slot
is derived from those two values.
Another way to write the last form in the above example would have been
(defmethod make-load-form ((self my-class))
(make-load-form-using-slots self '(a b)))
;; Example 2
(defclass my-frob ()
((name :initarg :name :reader my-name)))
(defmethod make-load-form ((self my-frob))
`(find-my-frob ',(my-name self) :if-does-not-exist :create))
In this example, instances of my-frob are "interned" in some way.
An equivalent instance is reconstructed by using the value of the
name slot as a key for searching existing objects. In this case
the programmer has chosen to create a new object if no existing
object is found; alternatively she could have chosen to signal an
error in that case.
;; Example 3
(defclass tree-with-parent () ((parent :accessor tree-parent)
(children :initarg :children)))
(defmethod make-load-form ((x tree-with-parent))
(values
;; creation form
`(make-instance ',(class-of x) :children ',(slot-value x 'children))
;; initialization form
`(setf (tree-parent ',x) ',(slot-value x 'parent))))
In this example, the data structure to be dumped is circular, because
each parent has a list of its children and each child has a reference
back to its parent. Suppose make-load-form is called on one object in
such a structure. The creation form creates an equivalent object and
fills in the children slot, which forces creation of equivalent
objects for all of its children, grandchildren, etc. At this point
none of the parent slots have been filled in. The initialization form
fills in the parent slot, which forces creation of an equivalent
object for the parent if it was not already created. Thus the entire
tree is recreated at load time. At compile time, MAKE-LOAD-FORM is
called once for each object in the true. All of the creation forms
are evaluated, in unspecified order, and then all of the
initialization forms are evaluated, also in unspecified order.
;; Example 4
(defstruct my-struct a b c)
(defmethod make-load-form ((s my-struct))
(make-load-form-using-slots s))
In this example, the data structure to be dumped has no special
properties and an equivalent structure can be reconstructed
simply by reconstructing the slots' contents.
Rationale:
Only the programmer who designed a class can know the correct
way to reconstruct objects of that class at load time, therefore
the reconstruction should be controlled by a generic function.
Using EVAL as the interface for telling LOAD what to do provides
full generality.
MAKE-LOAD-FORM returns two values so that circular structures can
be handled. If CONSTANT-CIRCULAR-COMPILATION is rejected,
MAKE-LOAD-FORM will only return one value, although implementations
that make an extension to support circular constants will probably
also make the extension to accept two values from MAKE-LOAD-FORM.
The default for class objects and structures is to signal an error,
rather than picking some particular object reconstruction technique,
because no reconstruction technique is appropriate for all objects.
It only takes two lines of code, as in example 4, to instruct the
compiler to use the technique that most often has been suggested
as the default.
MAKE-LOAD-FORM has a natural resemblance to PRINT-OBJECT, as a hook
for the programmer to control the system's actions.
The order of evaluation rules for creation and initialization forms
eliminate the possibility of partially initialized objects in the
absence of circular structures, and reduce it to the minimum possible
in the presence of circular structures. This allows nodes in
non-circular structures to be built out of fully initialized subparts.
Current practice:
Symbolics Flavors has something like this, but under a different name.
The name Symbolics uses is not suitable for standardization.
JonL reports that Lucid is getting more and more requests for this.
Cost to Implementors:
This seems like only a few one-line changes in the compiled-code
file writer and reader. MAKE-LOAD-FORM-USING-SLOTS is a couple
dozen lines of code, assuming the presence of the CLOS metaobject
protocol or an implementation-dependent equivalent.
Cost to Users:
None.
Cost of non-adoption:
Serious impairment of the ability to use extended-type objects. Each
implementation will probably make up its own version of this as an
extension.
Performance impact:
None.
Benefits:
See Cost of non-adoption.
Esthetics:
No significant positive or negative impact.
Discussion:
It would be possible to define an additional level of protocol that
allows multiple classes to contribute to the reconstruction of an
object, combining initialization arguments contributed by each class.
Since a user can easily define that in terms of MAKE-LOAD-FORM without
modifying the Lisp system, it is not being proposed now.
Any type that has a read syntax is likely to appear as a quoted
constant or inside a quoted constant. Pathnames are one example, user
programs often define others. Also many implementations provide a way
to create a compiled-code file full of data (rather than compiled Lisp
programs), and such data probably include extended-type objects.
Moon supports this. David Gray and John Rose made major contributions
to the discussion that produced this improved version 2 proposal.
∂09-Mar-89 1325 CL-Cleanup-mailer Issue: LOAD-OBJECTS (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 13:25:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554041; Thu 9-Mar-89 16:22:52 EST
Date: Thu, 9 Mar 89 16:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOAD-OBJECTS (Version 2)
To: John Rose <jrose@Sun.COM>
cc: CL-Cleanup@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU,
CL-Compiler@SAIL.STANFORD.EDU
In-Reply-To: <8901140458.AA18401@lukasiewicz.sun.com>
Message-ID: <19890309212238.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 13 Jan 89 20:58:49 PST
From: jrose@Sun.COM (John Rose)
...
The creation form for an object is always evaluated before the
initialization form for that object. When either the creation form or
the initialization form references other objects of user-defined types
that have not been referenced earlier in the COMPILE-FILE, the
compiler collects all of the creation forms together and collects all
of the initialization forms together. All of the creation forms are
evaluated before any of the initialization forms. The order of
evaluation of the creation forms is unspecified except when the
ordering is forced by data dependencies. The order of evaluation of
the initialization forms is unspecified.
...
Why does the proposal restrict the evaluation initialization forms to
such a late time? Data dependencies would allow an object X's
initialization form to be executed any time after X's creation form had
finished.
Actually, it would be better (and no more difficult, it seems to me) to
be strict in the other direction: Objects should be initialized as early
as possible, and hence at a deterministic time. This would allow nodes
in non-circular structures to be built out of fully initialized subparts,
which is clearly something an application could need.
Good point. I've modified the proposal accordingly, although I did not use
your exact wording. Of course the time is not fully determinstic, but
it's more deterministic than in version 2 of the proposal.
∂09-Mar-89 1421 CL-Compiler-mailer issue MACRO-ENVIRONMENT-EXTENT, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Mar 89 14:21:02 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA01983; Thu, 9 Mar 89 15:18:38 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA09917; Thu, 9 Mar 89 15:18:34 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903092218.AA09917@defun.utah.edu>
Date: Thu, 9 Mar 89 15:18:33 MST
Subject: issue MACRO-ENVIRONMENT-EXTENT, version 2
To: cl-compiler@sail.stanford.edu
This writeup ended up getting more changes than I anticipated. Here it
is in case anybody has any additional comments before I send it out
to X3J13.
Forum: Compiler
Issue: MACRO-ENVIRONMENT-EXTENT
References: CLtL p. 145-146
Issue COMPILER-LET-CONFUSION
Issue MACRO-CACHING
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue SYNTACTIC-ENVIRONMENT-ACCESS
CLOS Chapter 3 (89-003)
Category: CLARIFICATION,CHANGE
Edit History: V1, 10 Jan 1989, Sandra Loosemore
V2, 09 Mar 1989, Sandra Loosemore
Status: Ready for release
Problem Description:
What is the extent of environment objects received as the &ENVIRONMENT
argument of a macro function?
CLtL says that &ENVIRONMENT is "useful primarily in the rare cases
where a macro definition must explicitly expand any macros in a
subform of the macro call before computing its own expansion". While
this suggests that macro environment objects are typically used within
the dynamic scope of the macro function, the use of the word
"primarily" (rather than "only" or "exclusively" or some similarly
strong language) suggests that there may be other legitimate uses for
environment objects. But, because CLtL is silent about what those
uses might be, many users and implementors are under the impression
that environment objects have only dynamic extent.
There are some situations where using environment objects as if they
had indefinite extent provides a very useful viewpoint from which to
solve a problem. Consider the following example:
(defmacro typed-var (var) var)
(defmacro local-type-declare (declarations &body forms &environment env)
`(macrolet ((typed-var (&whole w var)
(let ((type (assoc var ',declarations)))
(if type
`(the ,(cadr type) ,var)
(macroexpand w ',env)))))
,@forms))
(defun f (x y)
(local-type-declare ((x fixnum) (y float))
(+ (typed-var x) (typed-var y))))
Here, local macro TYPED-VAR is defined to look first in the innermost
lexical environment for information about the variable, and if there
isn't any then it recurses on the next outermost lexical environment.
The global definition of TYPED-VAR provides a terminal case to stop
the recursion.
There are other situations where the extent of macro environment
objects comes into play. For example, if we allow caching of macro
expansions (issue MACRO-CACHING), environments must have indefinite
extent. It is unclear whether CLOS would be affected by allowing
macro environments to have only dynamic extent. (The descriptions of
the CLOS defining macros in document 89-003 seem to imply that the
value of the &ENVIRONMENT argument appears in the expansion of the
macro, but there now seems to be sentiment that the model of how the
defining macros work that is presented there is broken.)
Proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE:
State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or as the argument to a *MACROEXPAND-HOOK*
function have indefinite extent.
Note that implementations are not permitted to destructively modify
environment objects once they have been passed to a macro function.
Rationale:
This legitimizes the use of idioms which depend on macro environments
having indefinite extent.
Since data objects in Lisp otherwise have indefinite extent, it is
more consistent to give environment objects indefinite extent as
well.
Proposal MACRO-ENVIRONMENT-EXTENT:DYNAMIC:
State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or with a *MACROEXPAND-HOOK* function
have only dynamic extent; the consequences are undefined if they are
referred to outside the dynamic extent of that macro function or hook
function.
Rationale:
This allows implementations to use somewhat more efficient techniques
for representing environment objects. For example, the storage could
be stack-allocated, or environments could be bashed destructively
instead of always being freshly heap-allocated.
Proposal MACRO-ENVIRONMENT-EXTENT:DYNAMIC-WITH-COPIER:
State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or with a *MACROEXPAND-HOOK* function
have only dynamic extent; the consequences are undefined if they are
referred to outside the dynamic extent of that macro function or hook
function.
Add a new function:
COPY-ENVIRONMENT environment [function]
This function returns an environment object that is semantically
equivalent to "environment" (which must be an object of the type
received with an &ENVIRONMENT argument to a macro or as an argument to
a *MACROEXPAND-HOOK* function), but which may safely be referred to
outside the dynamic extent of the macro function. This function is
permitted to return an object that is EQ to its argument if that
object may be safely used.
Rationale:
This allows implementations to use somewhat more efficient techniques
for representing environment objects. For example, the storage could
be stack-allocated, or environments could be bashed destructively
instead of always being freshly heap-allocated.
It also allows programmers to use idioms that rely on environment
objects having indefinite extent.
Current Practice:
Macro environments appear to have indefinite extent in Lucid Common
Lisp, Kyoto Common Lisp, CMU Common Lisp (at least in the
interpreter), Utah Common Lisp, and A-Lisp. A-Lisp internally uses
the kind of idiom shown in the example above to implement FLET,
LABELS, and FUNCTION as macros.
Macro environments are stack-allocated in Symbolics Genera.
Cost to implementors:
For proposal INDEFINITE, some implementations may need to change. A
simple implementation of macro environments that would fit the
requirements of this proposal is to represent them as lists, pushing
information for inner contours onto the front of the list as the
contour is entered and popping the list when the contour is exited.
Implementations that now use some other representation, or that
stack-allocate environments, could make a copy of the environment
before expanding any macros.
For proposal DYNAMIC, there is no associated implementation cost.
For proposal DYNAMIC-WITH-COPIER, the implementation cost is unknown
but probably trivial in most implementations.
Cost to users:
For proposal INDEFINITE, there is no associated cost to users.
For proposal DYNAMIC, users would not be able to portably use a
simple and elegant approach to solving certain kinds of problems.
For proposal DYNAMIC-WITH-COPIER, users would have to remember to make
a copy of an environment object in some situations.
Benefits:
It is made clear whether treating environment objects as if they had
indefinite extent is portable usage.
Discussion:
Proposal SYNTACTIC-ENVIRONMENT-ACCESS:ADD-FUNCTIONAL-INTERFACE
includes adding a function called AUGMENT-ENVIRONMENT. It's unclear
whether having this function would eliminate the need for
COPY-ENVIRONMENT under proposal DYNAMIC-WITH-COPIER.
Loosemore supports proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE.
Moon says:
My opinion is that anything in CLOS that seems to depend on indefinite
extent for macro environments is broken and needs to be fixed. It's not
broken because of the environment extent, but for other reasons.
Thus I believe in dynamic extent for environments.
Neil Goldman says:
In my code walker I have a pretty ugly way of dealing with MACROLET
that would have been trivial if I could have counted on the
ENVIRONMENT having indefinite extent. There may be some cleaner way
than what I did, but I just looked at PCL's code walker, and it also
is much more complex than would be necessary if environments had
indefinite extent.
-------
∂09-Mar-89 1539 CL-Compiler-mailer Issue: LOCALLY-TOP-LEVEL (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 15:38:57 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554236; Thu 9-Mar-89 18:36:20 EST
Date: Thu, 9 Mar 89 18:36 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOCALLY-TOP-LEVEL (Version 1)
To: CL-Cleanup@sail.stanford.edu
cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>, CL-Compiler@sail.stanford.edu
In-Reply-To: <8903091815.AA09753@defun.utah.edu>
Message-ID: <19890309233609.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
This is a cleanup issue, but I'm cc'ing the compiler committee
for their information.
Issue: LOCALLY-TOP-LEVEL
References: None
Related issues: EVAL-WHEN-NON-TOP-LEVEL, DECLARATION-SCOPE
Category: CLARIFICATION / ADDITION
Edit history: Version 1, 9-Mar-89, by Moon
Problem description:
It is desirable to be able to wrap LOCALLY around one or more
top-level forms and have them continue to be treated as top-level
forms. Three examples of how this is useful:
- to put an OPTIMIZE or INLINE declaration into force around
several related forms.
- to put declarations into force around DEFCLASS, or any other
top-level form that lacks a syntax for embedded declarations.
- DECLARATION-SCOPE:LIMITED-HOISTING, which passed in January,
removed the ability to use a DECLARE at the head of the body of a
DEFUN or DEFMACRO to make a declaration that applies to the entire
form, including the lambda-list. We are supposed to use LOCALLY
instead, but forms in the body of LOCALLY are not top-level,
and that changes the semantics of DEFMACRO.
Issue EVAL-WHEN-NON-TOP-LEVEL could not define LOCALLY to treat
its body as top-level forms, because only a special form can do
that and LOCALLY is a macro.
Proposal (LOCALLY-TOP-LEVEL:SPECIAL-FORM):
Change LOCALLY from a macro to a special form, and change the
definition of compiler processing (in EVAL-WHEN-NON-TOP-LEVEL)
so that when a LOCALLY form appears at top level the forms in
its body are processed at top level.
Examples:
(locally (declare (optimize (safety 3) (space 3) (speed 0)))
(defmacro frob (&environment e x y &optional (z (foo x y)))
(mumble x y z e)))
Without this proposal, this would have to be written
(defmacro frob (&environment e x y &optional (z (locally
(declare
(optimize
(safety 3)
(space 3)
(speed 0)))
(foo x y))))
(locally (declare (optimize (safety 3) (space 3) (speed 0)))
(mumble x y z e)))
Rationale:
Wrapping LOCALLY around a form should not change its semantics except
as specified by the declarations, hence the body of a top-level
LOCALLY should be top-level.
A macro cannot have a top-level body unless it expands into a special
form that has a top-level body; otherwise the macro invocation and
the macro expansion would not have identical semantics as top-level
forms. There is no available special form for LOCALLY to macroexpand
into (CLtL doesn't say, but presumably the intent was to expand into
a LET with an empty binding list).
Current practice:
The Zetalisp equivalent of LOCALLY worked to surround top-level forms,
because it was a macro that expanded into COMPILER-LET (stashing the
declarations in a special variable the compiler would look at). This
is of course the wrong way to do declarations, but it shows that the
idea was that you could wrap declarations around a bunch of top-level
forms.
Symbolics Genera 7.4.0 does not implement the proposal (but it does
not implement DECLARATION-SCOPE:LIMITED-HOISTING either). I did
not survey any other implementations.
Cost to Implementors:
A half dozen lines of code in the compiler and a smaller amount
in the interpreter and any program-analyzing programs.
Cost to Users:
None.
Cost of non-adoption:
See the horrible example above.
Performance impact:
None.
Benefits:
More consistent language.
Esthetics:
Improved.
Discussion:
None.
∂09-Mar-89 1603 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Mar 89 16:03:26 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA05558; Thu, 9 Mar 89 17:01:21 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10059; Thu, 9 Mar 89 17:01:19 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903100001.AA10059@defun.utah.edu>
Date: Thu, 9 Mar 89 17:01:17 MST
Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 6
To: cl-compiler@sail.stanford.edu
-------
∂09-Mar-89 1609 CL-Compiler-mailer issue DEFINING-MACROS-NON-TOP-LEVEL, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Mar 89 16:09:36 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA05860; Thu, 9 Mar 89 17:07:30 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10083; Thu, 9 Mar 89 17:07:27 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903100007.AA10083@defun.utah.edu>
Date: Thu, 9 Mar 89 17:07:26 MST
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 8
To: cl-compiler@sail.stanford.edu
The definition of "top-level" has been moved to issue
EVAL-WHEN-NON-TOP-LEVEL. Otherwise this writeup is mostly
unchanged.
Forum: Compiler
Issue: DEFINING-MACROS-NON-TOP-LEVEL
References: CLtL p. 66-70, 143
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue COMPILER-LET-CONFUSION
Category: CLARIFICATION, ENHANCEMENT
Edit History: 6-May-88, V1 by Sandra Loosemore
9-Jun-88, V2 by Sandra Loosemore
12-Sep-88, V3 by Sandra Loosemore (fix garbled section 4)
21-Sep-88, V4 by Sandra Loosemore (clarify section 5)
16-Dec-88, V5 by Sandra Loosemore (major restructuring)
31-Dec-88, V6 by Sandra Loosemore (wording clarifications)
07-Jan-89, V7 by Sandra Loosemore (add example)
09-Mar-89, V8 by Sandra Loosemore (more restructuring)
Status: Ready for release
Problem Description:
CLtL leaves the interpretation of defining forms such as DEFMACRO and
DEFVAR that appear in other than top-level locations unclear.
On page 66, it is stated: "It is not illegal to use these forms at
other than top level, but whether it is meaningful to do so depends on
context. Compilers, for example, may not recognize these forms
properly in other than top-level contexts". At least one implementation
has interpreted this to mean that it is permissible to simply refuse
to compile defining macros that do not appear at top-level.
Proposal: DEFINING-MACROS-NON-TOP-LEVEL:ALLOW
(1) Remove the language from p. 66 of CLtL quoted above. Clarify that
while defining macros normally appear at top level, it is meaningful
to place them in non-top-level contexts and that the compiler must
handle them properly in all situations. However, the compile-time side
effects described in issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
only take place when the defining macros appear at top-level.
(2) Remove the language on p. 145 of CLtL, which states that macro
functions are always defined in the null lexical environment. Clarify
that all defining macros which create functional objects (including
DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
DEFSETF, as well as DEFUN) must ensure that those functions are
defined in the lexical environment in which the defining form is
evaluated.
(3) Specify that top-level forms in a file being compiled are
guaranteed to be processed sequentially. The order in which
non-top-level subforms of a top-level form are processed by the
compiler is explicitly left unspecified.
Rationale:
This proposal makes the rules for when defining macros cause
compile-time side effects to be exactly the same as the rules for when
(EVAL-WHEN (COMPILE) ...) causes compile-time evaluation. This
provides a simple implementation technique.
Item (3) serves two purposes. First, it guarantees users that
compile-time side-effects from top-level EVAL-WHEN forms or defining
macros will happen in the correct order; programmers can depend upon
the compile-time side-effects of a top-level form being visible during
the compilation of subsequent forms. Second, it allows compilers to
perform certain kinds of source-to-source transformations that change
the order of subforms.
For instance, the following example from CLtL
(let ((old-count *access-count*))
(unwind-protect
(progn
(incf *access-count*)
(perform-access))
(setq *access-count* old-count)))
is entirely equivalent to:
(let ((old-count *access-count*))
(let ((thunk #'(lambda () (setq *access-count* old-count))))
(unwind-protect
(progn
(incf *access-count*)
(perform-access))
(funcall thunk))))
(This is a real example from the A-Lisp compiler, which implements
UNWIND-PROTECT by having it push a "thunk" to perform the cleanup
actions onto the catch stack before executing the protected form.)
Current Practice:
Most implementations do allow defining macros in non-top-level places.
However, the rules for when they cause compile-time side-effects are
not always the same as those for EVAL-WHEN. This is the case in
Lucid Common Lisp, for example.
Cost to implementors:
Implementations that currently don't compile defining macros correctly
when they appear at non-top-level will have to be changed.
Cost to users:
None. This is a compatible extension.
Benefits:
The notion of defining macros as being somehow special when they
appear at top-level is removed, since their behavior can be explained
using EVAL-WHEN as a primitive. Allowing defining macros to appear
anywhere instead of restricting them to certain positions results in a
cleaner language design.
Discussion:
This proposal is consistent with the behavior specified in proposal
EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL. In particular, if the compile
time side-effects for defining macros specified in proposal
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY are implemented using
EVAL-WHEN, the "right" compiler behavior for defining macros at
non-top-level will happen automatically.
-------
∂09-Mar-89 1619 Common-Lisp-Object-System-mailer issue CLOS-MACRO-COMPILATION
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Mar 89 16:19:35 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA06189; Thu, 9 Mar 89 17:17:27 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10108; Thu, 9 Mar 89 17:17:24 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903100017.AA10108@defun.utah.edu>
Date: Thu, 9 Mar 89 17:17:22 MST
Subject: issue CLOS-MACRO-COMPILATION
To: Gregor.pa@Xerox.COM
Cc: cl-compiler@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
In-Reply-To: Gregor.pa@Xerox.COM, Thu, 23 Feb 89 20:23 PST
Have you made any progress yet on settling on your new model of how
the CLOS defining macros work? I have opened a new cl-compiler issue,
CLOS-MACRO-COMPILATION, for this, but I don't yet have a proposal.
(Or even a problem statement written down, for that matter.) I am
planning to distribute the rest of our issues to X3J13 early next
week and would like to have at least a draft ready by then. If you
don't think that's possible, I will have to say in our report that
we need an extension to get this issue resolved.
-Sandra
-------
∂09-Mar-89 1606 CL-Compiler-mailer issue EVAL-WHEN-NON-TOP-LEVEL, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Mar 89 16:06:24 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA05662; Thu, 9 Mar 89 17:04:14 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10071; Thu, 9 Mar 89 17:04:10 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903100004.AA10071@defun.utah.edu>
Date: Thu, 9 Mar 89 17:04:08 MST
Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 6
To: cl-compiler@sail.stanford.edu
[How did the mailer lose the text to this message when I sent it out
before?]
With the help of Pitman and Moon, I have cleaned up the presentation
of the GENERALIZE-EVAL proposal from version 5. Among other things, I
have moved the definition of "top-level" here (from issue
DEFINING-MACROS-NON-TOP-LEVEL), so there is now a more coherent
description of how the compiler processes top-level forms. (If
anybody has been looking over the working draft of the standard, that
description is going to end up in section 4.2.)
Issue: EVAL-WHEN-NON-TOP-LEVEL
Forum: Compiler
References: EVAL-WHEN (CLtL pp69-70),
Issue DEFINING-MACROS-NON-TOP-LEVEL
Issue COMPILED-FUNCTION-REQUIREMENTS
Issue IN-PACKAGE-FUNCTIONALITY
Issue LOCALLY-TOP-LEVEL
Category: CLARIFICATION/CHANGE
Edit History: 06-May-88, Version 1 by Sandra Loosemore
16-Dec-88, Version 2 by Loosemore (alternate direction)
30-Dec-88, Version 3 by Loosemore (minor wording changes)
07-Jan-89, Version 4 by Loosemore (update discussion)
09-Feb-89, Version 5 by Pitman and Moon (some major changes)
09-Mar-89, Version 6 by Loosemore (clean up wording)
Status: Ready for release
Problem Description:
The current description of how the compiler should handle EVAL-WHEN
only makes sense when it appears as a top-level form in the file being
compiled. Is it legitimate for EVAL-WHEN to appear in non-top-level
locations? Even if it is legitimate, what does it mean?
Another issue, referred to here as ``the EVAL-WHEN shadowing problem,''
is that some people have complained that shadowing the symbols EVAL,
COMPILE, or LOAD means that you have to also either shadow EVAL-WHEN
and define it to recognize the new symbol, or else you must resign
yourself to writing (EVAL-WHEN (... LISP:EVAL ...) ...),etc. all over.
While the goal here is not to solve this problem, it might be possible
to solve both problems at once.
There are two proposals presented here, GENERALIZE-EVAL and
GENERALIZE-EVAL-NEW-KEYWORDS.
Background/Analysis:
The proposal which follows was constructed with the following goals
in mind:
1. The lexical and dynamic environment for the EVAL-WHEN body should
be the same for each situation. That is, the body should ``mean
the same thing'' regardless of which situation is being processed.
2. The evaluation context for EVAL-WHEN should be the current
lexical environment.
3. At execution time, EVAL-WHEN should always return the result of
its last form if execution of the body occurred, or NIL if the
body was not executed.
4. If a top-level EVAL-WHEN has a LOAD keyword, its body should
inherit top-level-ness during normal processing. This permits the
use of (EVAL-WHEN (EVAL COMPILE LOAD) ...) at top-level to mean
simply "Do whatever would normally be done for this body, but
also do something at compile time." This, in turn, will later be
the key to allowing defining forms to be usefully described in
terms of EVAL-WHEN.
5. Non-top-level expressions should have no effect until they are
executed. This is the key to making sure that any necessary
environment is present. Since the COMPILE keyword forces effects
to occur earlier than execution time, it follows from this that
any correct solution must not allow the COMPILE keyword to have
an effect at other than top-level.
To accomplish these goals, we formulated the following model:
The purpose of EVAL-WHEN is to accomodate the fact that some of the
semantic processing of an expression may usefully be partitioned
between compile time and run time in some circumstances.
(EVAL-WHEN (EVAL) <code>)
describes a general technique for accomplishing some particular goal
at normal program execution time. However, the pair of expressions
(EVAL-WHEN (COMPILE) <code-A>)
(EVAL-WHEN (LOAD) <code-B>)
can be used to describe an alternate technique for implementing part
of the effect (A) at compile-time, and part of the effect (B) at
load-time.
Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL):
Replace the description of EVAL-WHEN with the following:
EVAL-WHEN ({situation}*) {form}* [Special Form]
The body of an EVAL-WHEN form is processed as an implicit PROGN, but
only in the situations listed. Each SITUATION must be a symbol,
either COMPILE, LOAD, or EVAL.
The use of COMPILE and LOAD controls whether and when processing
occurs for top-level forms. The use of EVAL controls whether
processing occurs for non-top-level forms.
The EVAL-WHEN construct may be more precisely understood in terms of
a model of how the file compiler, COMPILE-FILE, processes forms in a
file to be compiled.
Successive forms are read from the file by the file compiler using
READ. These top-level forms are normally processed in what we call
`not-compile-time' mode. There is one other mode, called
`compile-time-too' mode, which can come into play for top-level
forms. The EVAL-WHEN special form is used to annotate a program
in a way that allows the program doing the processing to select
the appropriate mode.
Processing of top-level forms in the file compiler works as follows:
* If the form is a macro call, it is expanded and the result is
processed as a top-level form in the same processing mode
(compile-time-too or not-compile-time).
* If the form is a PROGN form, each of its body forms is
sequentially processed as top-level forms in the same processing
mode.
* If the form is a COMPILER-LET, MACROLET, or SYMBOL-MACROLET,
the file compiler makes the appropriate bindings and recursively
processes the body forms as an implicit top-level PROGN with those
bindings in effect, in the same processing mode.
* If the form is an EVAL-WHEN form, it is handled according to
the following table:
COMPILE LOAD EVAL compile-time-too Action
Yes Yes -- -- Process body in compile-time-too mode
No Yes Yes Yes Process body in compile-time-too mode
No Yes Yes No Process body in not-compile-time mode
No Yes No -- Process body in not-compile-time mode
Yes No -- -- Evaluate body
No No Yes Yes Evaluate body
No No Yes No do nothing
No No No -- do nothing
"Process body" means to process the body as an implicit top-level
PROGN. "Evaluate body" means to evaluate the body forms as in
implicit PROGN in the dynamic execution context of the compiler and
in the lexical environment in which the EVAL-WHEN appears.
* Otherwise, the form is a top-level form that is not one of the
special cases. If in compile-time-too mode, the compiler first
evaluates the form and then performs normal compiler processing
on it. If in not-compile-time mode, only normal compiler
processing is performed. [The nature of this processing is
defined more precisely in issue COMPILED-FUNCTION-REQUIREMENTS.]
Any subforms are treated as non-top-level forms.
For an EVAL-WHEN form that is not a top-level form in the file compiler
(that is, one of: in the interpreter; in COMPILE; or in the file
compiler but not at top-level), if the EVAL situation is specified,
its body is treated as an implicit PROGN. Otherwise, the EVAL-WHEN
form returns NIL.
Clarifications/Consequences:
The following effects are logical consequences of the above proposal:
* It is never the case that the execution of a single EVAL-WHEN
expression will execute the body code more than once.
* The keyword `EVAL' is a misnomer because execution of
the body need not be done by EVAL. In compiled code, such as
(DEFUN FOO () (EVAL-WHEN (EVAL) (PRINT 'FOO)))
the call to PRINT should be compiled.
* Macros intended for use in top-level forms should arrange for all
side-effects to be done by the forms in the macro expansion.
The macro-expander itself should not do the side-effects.
Wrong: (defmacro foo ()
(really-foo)
`(really-foo))
Right: (defmacro foo ()
`(eval-when (compile eval load) (really-foo)))
Adherence to this convention will mean that such macros will behave
intuitively when placed in non-top-level positions.
* Placing a variable binding around an EVAL-WHEN reliably captures the
binding because the `compile-time-too' mode cannot occur (because
introducing a variable binding would mean we were not at top level).
For example,
(LET ((X 3))
(EVAL-WHEN (EVAL LOAD COMPILE) (PRINT X)))
will print 3 at execution [load] time, and will not print anything at
compile time. This is important so that expansions of DEFUN and
DEFMACRO can be done in terms of EVAL-WHEN and can correctly capture
the lexical environment.
(DEFUN BAR (X) (DEFUN FOO () (+ X 3)))
might expand into
(DEFUN BAR (X)
(PROGN (EVAL-WHEN (COMPILE)
(COMPILER::NOTICE-FUNCTION-DEFINITION 'FOO '(X)))
(EVAL-WHEN (EVAL LOAD)
(SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))))
which would be treated the same as
(DEFUN BAR (X)
(SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))
by the above rules.
Test Cases:
;; #1: The EVAL-WHEN in this case is not at top-level, so only the EVAL
;; keyword is considered. At compile time, this has no effect.
;; At load time (if the LET is at top level), or at execution time
;; (if the LET is embedded in some other form which does not execute
;; until later) this sets (SYMBOL-FUNCTION 'FOO1) to a function which
;; returns 1.
(LET ((X 1))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO1) #'(LAMBDA () X))))
;; #2: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting
;; (SYMBOL-FUNCTION 'FOO2) to a function which returns 2.
(EVAL-WHEN (EVAL LOAD COMPILE)
(LET ((X 2))
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO2) #'(LAMBDA () X)))))
;; #3: If this expression occurs at the top-level of a file to be compiled,
;; it has BOTH a compile time AND a load-time effect of setting the
;; function cell of FOO3 to a function which returns 3.
(EVAL-WHEN (EVAL LOAD COMPILE)
(SETF (SYMBOL-FUNCTION 'FOO3) #'(LAMBDA () 3)))
;; #4: This always does nothing. It simply returns NIL.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (COMPILE)
(PRINT 'FOO4)))
;; #5: If this form occurs at top-level of a file to be compiled, FOO5 is
;; printed at compile time. If this form occurs in a non-top-level
;; position, nothing is printed at compile time. Regardless of context,
;; nothing is ever printed at load time or execution time.
(EVAL-WHEN (COMPILE)
(EVAL-WHEN (EVAL)
(PRINT 'FOO5)))
;; #6: If this form occurs at top-level of a file to be compiled, FOO6 is
;; printed at compile time. If this form occurs in a non-top-level
;; position, nothing is printed at compile time. Regardless of context,
;; nothing is ever printed at load time or execution time.
(EVAL-WHEN (EVAL LOAD)
(EVAL-WHEN (COMPILE)
(PRINT 'FOO6)))
Rationale:
This is compatible with any guarantees made by CLtL, and extends the
behavior usefully to non-top-level situations.
This gives a useful meaning to EVAL-WHEN that supports useful and
predictable behavior if defining macros are used in a non-top-level
situation.
Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS):
As in GENERALIZE-EVAL, but rename the EVAL keyword to :EXECUTE,
the COMPILE keyword to :COMPILE-TOPLEVEL, and LOAD keyword to
:LOAD-TOPLEVEL.
Deprecate the use of keywords EVAL, COMPILE, and LOAD to EVAL-WHEN.
For compatibility, they are supported in EVAL-WHEN
at top-level, but their meaning is not defined elsewhere.
Rationale:
The fact that the situation keywords chosen are not the same as
those now used means that the change can be added in a way that
is truly upward compatible (not only with CLtL but with existing
practice in implementations which have chosen to extend or `clarify'
the definition given in CLtL) since the meaning of EVAL, COMPILE,
and LOAD in non-top-level situations (which was never spelled
out in CLtL) can legitimately differ from the meaning of these
new keywords.
Using other names and/or the keyword package for the names of
situations solves the EVAL-WHEN shadowing problem.
The name `execute' does not promote the confusion that the body of an
EVAL-WHEN must be executed only in the evaluator. It also does not
promote the confusion that the body of an EVAL-WHEN, regardless of when
executed, must run interpreted.
The names `compile-toplevel' and `load-toplevel' emphasize the fact
that these cases are not interesting in non-top-level positions.
Current Practice:
In Symbolics Genera, the interpreter permits EVAL-WHEN in non-top-level
positions in a way that is compatible with this proposal but both the
COMPILE and COMPILE-FILE functions complain about EVAL-WHEN in a
non-top-level position.
Both Lucid Common Lisp and Kyoto Common Lisp already interpret the
EVAL keyword to mean "execute" in non-top-level situations. Both of
these implementations also make (EVAL-WHEN (LOAD) ...) suppress
compile-time "magic" from defining macros such as DEFMACRO.
IIM describes its EVAL-WHEN as:
(defmacro eval-when (situations &body body &environment env)
(if (not (compiler-environment-p env))
(when (member 'eval situations) `(progn ,@body))
(progn
(when (member 'compile situations)
(if (compiler-at-top-level-p env)
(mapc #'eval body)
(warn "Top-level form encountered at non-top-level.")))
(when (member 'load situations) `(progn ,@body)))))
Note that the interpretation of the EVAL situation and the nesting
behavior is different.
Cost to Implementors:
The actual change to EVAL-WHEN in both cases is probably fairly
localized and straightforward to make in most or all implementations.
The second-order costs of proposal GENERALIZE-EVAL will vary depending
on whether existing implementations have extended the definition of
EVAL-WHEN in incompatible ways. If an implementation has made such
extensions, there may be user and system code which depends on them
and the cost of converting that code may be non-trivial. There is
presumably also documentation impact.
Proposal GENERALIZE-EVAL-NEW-KEYWORDS avoids most or all of the
second-order costs of proposal GENERALIZE-EVAL.
The compiler processing for top-level forms might be implemented
something like:
;;; Forms read by the file compiler are passed to PROCESS-TOP-LEVEL-FORM
;;; with a env compile-time-too both NIL.
(defun process-top-level-form (form env compile-time-too)
(setq form (macroexpand form env))
(cond ((not (consp form))
nil)
((eq (car form) 'progn)
(dolist (f (cdr form))
(process-top-level-form f env compile-time-too)))
((eq (car form) 'compiler-let)
(process-compiler-let form env compile-time-too))
((eq (car form) 'macrolet)
(process-macrolet form env compile-time-too))
((eq (car form) 'symbol-macrolet)
(process-symbol-macrolet form env compile-time-too))
((eq (car form) 'eval-when)
(process-eval-when form env compile-time-too))
(t
(if compile-time-too
(internal-eval form env))
(compile-form form env))
))
(defun process-eval-when (form env compile-time-too)
(let* ((situations (cadr form))
(body (cddr form))
(compile-p (member 'compile situations))
(load-p (member 'load situations))
(eval-p (member 'eval situations)))
(cond ((or (and compile-p load-p)
(and eval-p load-p compile-time-too))
(process-top-level-form `(progn ,@body) env t))
(load-p
(process-top-level-form `(progn ,@body) env nil))
((or compile-p
(and eval-p compile-time-too))
(dolist (f body)
(internal-eval f env)))
(t
nil))))
;;; PROCESS-COMPILER-LET, PROCESS-MACROLET, and PROCESS-SYMBOL-MACROLET
;;; do the obvious things.
;;; INTERNAL-EVAL evaluates "form" in lexical environment "env".
Cost to Users:
Technically, none. Either proposal is technically upward compatible
with CLtL.
Proposal GENERALIZE-EVAL might force some extended implementations to
change incompatibly. As such, some users who depend on
implementation-dependent extensions might have to adjust their code
somewhat to deal with those changes.
Proposal GENERALIZE-EVAL-NEW-KEYWORDS does not force implementations
to change incompatibly, so has no forced impact on users.
Cost of Non-Adoption:
EVAL-WHEN is a mess. Using it as the low-level substrate into which
defining macros should expand, and guaranteeing any predictable effects
of those macros in non-top-level situations is currently difficult and
would continue to be so in the absence of some resolution on this issue.
Benefits:
The costs of non-adoption would be avoided: it would be possible to
use EVAL-WHEN in many situations where it cannot currently be used
reliably.
The portability of many existing tools which use EVAL-WHEN internally
in macros will be enhanced.
Aesthetics:
This generalization of the meaning makes the purpose and uses of
EVAL-WHEN less mysterious. In that sense, aesthetics are simplified
somewhat.
Discussion:
The cleanup issue LOCALLY-TOP-LEVEL would make LOCALLY also "pass
through" top-level-ness to its body. The reason why that is not
addressed in this issue is that it involves making LOCALLY a special
form.
Pitman and Moon don't care whether we say `top level,' `top-level,' or
`toplevel.' The spelling choices in this writeup are arbitrary. If
necessary, the proposal GENERALIZE-EVAL-NEW-KEYWORDS could be amended
to propose :COMPILE-TOP-LEVEL, etc.
Pitman, Moon, and Bob Laddaga (a Symbolics Cloe implementor) support
both of these proposals. Pitman and Laddaga have a preference for
GENERALIZE-EVAL-NEW-KEYWORDS. Moon is neutral about which should be
preferred.
Sandra Loosemore says:
I still feel somewhat uncomfortable with the definition of EVAL-WHEN
presented here, mostly because its nesting behavior is so unintuitive
(as in test case number 6). We have also had a hard time in deciding
what the term "top-level" really means; the definition presented here
is rather arbitrary. However, since we have run out of time in which
to come up with acceptable alternatives, I'm willing to go along with
proposal GENERALIZE-EVAL. It is compatible with the description in
CLtL but presented in a more coherent way, and I think it is an
improvement. On the other hand, I don't really like the idea of
changing the names of the keywords; if we are going to make an
incompatible change, the right thing to do would be to throw out
EVAL-WHEN entirely and start from scratch.
-------
∂09-Mar-89 1652 CL-Compiler-mailer cl-compiler issue status as of 3/9
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Mar 89 16:52:46 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA06843; Thu, 9 Mar 89 17:50:41 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10126; Thu, 9 Mar 89 17:50:39 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903100050.AA10126@defun.utah.edu>
Date: Thu, 9 Mar 89 17:50:38 MST
Subject: cl-compiler issue status as of 3/9
To: cl-compiler@sail.stanford.edu
OK, here's where we stand now.
This is the list of issues which I think will be ready to send out in
time to meet the 2-week rule. The ones marked with an asterisk are
the ones that I've sent out new versions on in the past day or two.
My plan is to mail all of these to X3J13 Monday night, but please
don't wait until the last minute if you have some major complaint that
you haven't told me about yet. As far as I'm aware, none of these
issues require major changes but on some of them I do have some notes
about updating things like current practice or error terminology.
* COMPILE-ENVIRONMENT-CONSISTENCY
COMPILE-FILE-SYMBOL-HANDLING
COMPILED-FUNCTION-REQUIREMENTS
COMPILER-DIAGNOSTICS
* COMPILER-LET-CONFUSION
COMPILER-VERBOSITY
CONSTANT-CIRCULAR-COMPILATION
CONSTANT-COLLAPSING
CONSTANT-COMPILABLE-TYPES
* DEFINING-MACROS-NON-TOP-LEVEL
* EVAL-WHEN-NON-TOP-LEVEL
LOAD-TIME-EVAL
* MACRO-ENVIRONMENT-EXTENT
QUOTE-SEMANTICS
SAFE-CODE
Unless somebody sends me revised proposals Real Soon Now, it doesn't
look like these issues are going to be ready in time to meet the
2-week rule:
CLOS-MACRO-COMPILATION
COMPILE-FILE-ENVIRONMENT
DEFCONSTANT-NOT-WIRED
DEFINE-OPTIMIZER
PROCLAIM-ETC-IN-COMPILE-FILE
SYNTACTIC-ENVIRONMENT-ACCESS (aka MACRO-ENVIRONMENT-CREATOR)
WITH-COMPILATION-UNIT
Issue CLOS-MACRO-COMPILATION is troublesome. If we can't come up with
a proposal before the meeting, I think we'll have to ask for an
extension. I don't think the standard would be complete without
saying something on this issue -- it's not a proposal for an addition
to the language, it's a clarification of the compilation semantics of
a basic language feature.
-Sandra
-------
∂09-Mar-89 1708 CL-Compiler-mailer issue CLOS-MACRO-COMPILATION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89 17:08:20 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554334; Thu 9-Mar-89 20:05:08 EST
Date: Thu, 9 Mar 89 20:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CLOS-MACRO-COMPILATION
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: Gregor.pa@Xerox.COM, cl-compiler@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8903100017.AA10108@defun.utah.edu>
Message-ID: <19890310010446.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 9 Mar 89 17:17:22 MST
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Have you made any progress yet on settling on your new model of how
the CLOS defining macros work?
I didn't get a chance to talk with Gregor when he was here a couple
days ago, but I have made some progress on this myself. However, it's
not ready to show to anyone yet.
I have opened a new cl-compiler issue,
CLOS-MACRO-COMPILATION, for this, but I don't yet have a proposal.
(Or even a problem statement written down, for that matter.) I am
planning to distribute the rest of our issues to X3J13 early next
week and would like to have at least a draft ready by then. If you
don't think that's possible, I will have to say in our report that
we need an extension to get this issue resolved.
What I'm doing won't be ready to show to X3J13 that soon. However,
assuming that eval-when is settled now, I don't think what I'm doing
will have any effect on X3J13 as it should be all at the metaobject
level. I guess I won't know that for sure until I'm done.
∂09-Mar-89 1920 CL-Cleanup-mailer Re: Potential issue: MACRO-SPECIAL-FORMS
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 9 Mar 89 19:19:59 PST
Received: from Semillon.ms by ArpaGateway.ms ; 09 MAR 89 19:14:55 PST
Date: Thu, 9 Mar 89 19:14 PST
From: Gregor.pa@Xerox.COM
Subject: Re: Potential issue: MACRO-SPECIAL-FORMS
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>, Kent M Pitman
<KMP@STONY-BROOK.SCRC.Symbolics.COM>, cl-compiler@sail.stanford.edu,
cl-cleanup@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-5.text.newest
In-Reply-To: <19890308022127.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890310031441.0.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
I agree with Moon's position on this.
I have written my own code walker for use in PCL. I keep having to add
special forms to it anyways, and it turns out it is much easier to do
that than deal with screwy "expansions" of "macros".
-------
∂09-Mar-89 2220 CL-Compiler-mailer issue MACRO-ENVIRONMENT-EXTENT, version 2
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 9 Mar 89 22:20:53 PST
Received: from GANG-GANG.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 280104; Fri 10-Mar-89 01:17:50 EST
Date: Fri, 10 Mar 89 01:18 EST
From: Glenn S. Burke <gsb@ALDERAAN.SCRC.Symbolics.COM>
Subject: issue MACRO-ENVIRONMENT-EXTENT, version 2
To: sandra%defun@cs.utah.edu, cl-compiler@sail.stanford.edu
In-Reply-To: <8903092218.AA09917@defun.utah.edu>
Message-ID: <19890310061817.9.GSB@GANG-GANG.SCRC.Symbolics.COM>
I believe in dynamic extent for macro environments. The efficiency
penalty of doing otherwise increases as more functionality becomes
attached to macro environments.
I have serious doubts that adding a copier for macro environments would
help, because of the quantity of data which might need to be copied:
this could conceivably be a compiler's entire model of a compilation
destination (type proclamations, defmacro definitions, etc).
Most if not all of the examples i've seen which purport to require
indefinite extent for macroexpansion environments would be better done
(easier to read and understand, easier to implement efficiently) by
special constructs designed for the purpose.
∂09-Mar-89 2315 CL-Compiler-mailer Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from ECLA.USC.EDU by SAIL.Stanford.EDU with TCP; 9 Mar 89 23:14:51 PST
Date: Thu 9 Mar 89 23:12:17-PST
From: Kim A. Barrett <IIM@ECLA.USC.EDU>
Subject: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: cl-compiler@SAIL.STANFORD.EDU
cc: iim@ECLA.USC.EDU
Message-ID: <12476822375.25.IIM@ECLA.USC.EDU>
Major changes from version 2.
1. ENVIRONMENT-TARGET => ENVIRONMENT-REMOTE-P
2. Dropped the ENVIRONMENT- prefix from the accessors, and made the env
arguments optional (Gray's suggestion).
3. TYPE and FTYPE information made optional.
4. AUGMENT-ENVIRONMENT: Replaced :lexical argument with :variable argument,
taking on the responsibility of seperating lexicals from specials based on
the :special argument and global proclamations.
5. New stuff: WITH-REMOTE-ENVIRONMENT, RECORD-ENVIRONMENT-CLEANUP, and
MAKE-NULL-ENVIRONMENT.
6. Significant rewrites of various sections in response to comments. Hopefully
this version will be found less confusing and better motivated.
kab
-----
Issue: SYNTACTIC-ENVIRONMENT-ACCESS
References: CLtL Chapter 8: Macros,
Issue MACRO-FUNCTION-ENVIRONMENT,
Issue GET-SETF-METHOD-ENVIRONMENT,
Issue COMPILE-FILE-ENVIRONMENT
Related Issues: Issue FUNCTION-NAME,
Issue PROCLAIM-LEXICAL
Category: ADDITION
Edit history: Version 1, 2-Oct-88, Eric Benson
Version 2, 17-Feb-89, Kim A. Barrett
Version 3, 9-Mar-89, Kim A. Barrett (respond to comments)
Status: For internal discussion
Problem description:
When macro forms are expanded, the expansion function is called with two
arguments: the form to be expanded, and the environment in which the form was
found. The environment argument is of limited utility. The only use
sanctioned currently is as an argument to MACROEXPAND or MACROEXPAND-1 or
passed directly as an argument to another macro expansion function. Recent
cleanup issues propose to allow it as an argument to MACRO-FUNCTION and to
GET-SETF-METHOD.
Implementing the FIND-CLASS and ENSURE-GENERIC-FUNCTION functions of CLOS
requires the ability to distinguish between environments used for compiling to
a file from those used for processing in-core, such as by EVAL or COMPILE.
Resolution of the LOAD-TIME-EVAL issue may also require this information.
This problem has been addressed by the recent cleanup issue
COMPILE-FILE-ENVIRONMENT. Also, it has proven impossible to write a portable
code walker in Common Lisp, due to insufficient access to the information
contained in environments and the inability to augment environments with local
function definitions.
Proposal (SYNACTIC-ENVIRONMENT-ACCESS:ADD-FUNCTIONAL-INTERFACE):
The following functions provide information about syntactic environment
objects. In all of these functions the argument named ENV is an environment
of the sort received by the &ENVIRONMENT argument to a macro or as the
environment argument for EVALHOOK. NIL is the local null lexical environment,
and is therefore considered to be a syntactic environment. All of these
functions should signal an error of type TYPE-ERROR if the value of an
environment argument is not a syntactic environment.
ENVIRONMENT-REMOTE-P env [Function]
Returns true if ENV is a remote environment, false otherwise.
VARIABLE-KIND variable &optional env [Function]
VARIABLE is a symbol. This function returns one of the folloing symbols,
depending on the type of definition or binding which is apparent in ENV.
NIL There is no apparent definition or binding for variable.
:SPECIAL VARIABLE refers to a special variable, either declared or
proclaimed.
:LEXICAL VARIABLE refers to a lexical variable.
:SYMBOL-MACRO VARIABLE refers to a SYMBOL-MACROLET binding.
:CONSTANT VARIABLE refers to a named constant, defined by DEFCONSTANT.
[Note: If issue PROCLAIM-LEXICAL passes, then the :LEXICAL result will also
refer to variables proclaimed lexical.]
Example:
(DEFMACRO KIND-OF-VARIABLE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-KIND VAR ENV))
(DEFVAR A)
(DEFUN TEST ()
(LET (B)
(LET (C)
(DECLARE (SPECIAL C))
(SYMBOL-MACROLET ((D ANYTHING))
(LIST (KIND-OF-VARIABLE A)
(KIND-OF-VARIABLE B)
(KIND-OF-VARIABLE C)
(KIND-OF-VARIABLE D)
(KIND-OF-VARIABLE E))))))
(TEST) -> (:SPECIAL :LEXICAL :SPECIAL :SYMBOL-MACRO NIL)
FUNCTION-KIND function &optional env [Function]
FUNCTION is a function name. This function returns two values, depending on
the type of function definition or function binding which is apparent for
FUNCTION in ENV.
NIL There is no apparent definition for FUNCTION.
:FUNCTION FUNCTION refers to a function.
:MACRO FUNCTION refers to a macro.
:SPECIAL-FORM FUNCTION refers to a special-form.
The second value specifies whether the definition is local or global. If
local, the second value is true, and it is false when the definition is
global.
Some function names may refer to both a global macro and a global special
form. In such a case, the macro takes precedence, and :MACRO is returned as
the first value.
[Note: The use of "function name" rather than "symbol" as the description of
the function argument is intended to be compatible with the various proposals
to extend the syntax of function specifiers. If no such change actually
occurs then this would only refer to symbols.]
Example:
(DEFMACRO KIND-OF-FUNCTION (FUNCTION-NAME &ENVIRONMENT ENV)
`',(FUNCTION-KIND FUNCTION-NAME ENV))
(DEFUN A ())
(DEFMACRO B ())
(DEFUN TEST ()
(FLET ((C ()))
(MACROLET ((D ()))
(MULTIPLE-VALUE-CALL #'LIST
(KIND-OF-FUNCTION A)
(KIND-OF-FUNCTION B)
(KIND-OF-FUNCTION QUOTE)
(KIND-OF-FUNCTION C)
(KIND-OF-FUNCTION D)
(KIND-OF-FUNCTION E)))))
(TEST) -> (:FUNCTION NIL
:MACRO NIL
:SPECIAL-FORM NIL
:FUNCTION T
:MACRO T
NIL NIL)
VARIABLE-TYPE variable &optional env [Function]
VARIABLE is a symbol. This function returns the type specifier
associated with the variable named by the symbol in the environment.
If no explicit association exists, either by PROCLAIM or DECLARE, then
the result is the type specifier T.
The result of this function may not include all the apparent TYPE
declarations for VARIABLE. In particular, an implementation is free to
ignore TYPE declarations, only returning TYPE information which was added to
ENV by a call to AUGMENT-ENVIRONMENT.
Example:
This example assumes that the implementation records type information in the
environment, rather than ignoring it.
(DEFMACRO VARTYPE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-TYPE VAR ENV))
(DEFVAR A 1)
(PROCLAIM '(FIXNUM A))
(DEFUN TEST ()
(LET ((B (AREF "X" 0))
(C 3))
(DECLARE (STRING-CHAR B))
(LIST (VARTYPE A) (VARTYPE B) (VARTYPE C))))
(TEST) -> (FIXNUM STRING-CHAR NIL)
FUNCTION-FTYPE function &optional env [Function]
FUNCTION is a function name. This function returns the functional type
specifier associated with the function in the environment, or the symbol
FUNCTION if there is no functional type declaration or proclamation
associated with the function.
The result of this function may not include all the apparent FTYPE
declarations for FUNCTION. In particular, an implementation is free to
ignore FTYPE declarations, only returning FTYPE information which was added
to ENV by a call to AUGMENT-ENVIRONMENT.
Example:
This example assumes that the implementation records ftype information in the
environment, rather than ignoring it.
(DEFMACRO FUNTYPE (FUN &ENVIRONMENT ENV)
`',(FUNCTION-FTYPE FUN ENV))
(DEFUN A-FUNCTION (X)
(+ X 3))
(PROCLAIM '(FTYPE (FUNCTION (FIXNUM) FIXNUM) A-FUNCTION))
(DEFUN TEST ()
(FLET ((ANOTHER-FUNCTION (X)
(+ X 2)))
(DECLARE (FTYPE (FUNCTION (INTEGER) INTEGER) ANOTHER-FUNCTION))
(LIST (FUNTYPE A-FUNCTION) (FUNTYPE ANOTHER-FUNCTION))))
(TEST) -> ((FUNCTION (FIXNUM) FIXNUM) (FUNCTION (INTEGER) INTEGER))
AUGMENT-ENVIRONMENT env &KEY variable
special
symbol-macro
function
macro
type
ftype [Function]
This function returns a copy of ENV, augmented with the information provided
by the keyword arguments. The arguments are supplied as follows:
:VARIABLE A list of symbols which shall be visible as bound variables in
the new environment. Whether each binding is to be interpreted
as dynamic or lexical depends on the value of the :SPECIAL
argument and SPECIAL proclamations recorded in the environment.
:SPECIAL A list of symbols which shall be visible as dynamic variables
in the new environment. If a symbol in this list also appears
in the :VARIABLE list, then the binding is to be interpreted as
being dynamic.
:SYMBOL-MACRO An alist of symbols and macroexpansions. The new environment
will have local symbol-macro bindings of each symbol to the
corresponding expansion, so that MACROEXPAND will be able to
expand them properly.
:FUNCTION A list of function names which shall be visible as local
function bindings in the new environment.
:MACRO An alist of function names and macroexpansion functions. The
new environment will have local macro bindings of each name to
the corresponding expander function, which will be returned by
MACRO-FUNCTION and used by MACROEXPAND.
:TYPE An alist of symbols and type specifiers. The new environment
will have the type specifier associated with the currently
visible binding of the symbol (defaulting to the global special
binding if there is no binding present). Note that in a single
call to AUGMENT-ENVIRONMENT the :TYPE argument can be thought
of as being processed after all the variable arguments have
been processed, thus allowing bindings and declarations to be
updated with a single call.
:FTYPE An alist of function names and functional type specifiers.
This is analogous to :TYPE, exept operating in the function
namespace.
An error is signaled if any of the symbols specified as keys in the
:SYMBOL-MACRO alist are also included in either the :VARIABLE or :SPECIAL
lists, or are among the key symbols in the :TYPE alist. An error is signaled
if any of the names specified as keys in the :MACRO alist are also included
in the :FUNCTION list. It is an error to modify the list structure of any of
the arguments to this function.
If the ENV argument is a remote environment, then the new environment
returned by this function will also be remote, and the two will refer to the
same model of the remote environment. The extent of the returned environment
is the same as the extent of the argument.
While an environment argument from EVALHOOK may be used as the environment
argument for this function, the reverse is not true. It is an error to
attempt to use the result of AUGMENT-ENVIRONMENT as the environment argument
for EVALHOOK. The environment returned by AUGMENT-ENVIRONMENT may only be
used for syntactic analysis, ie. the functions specified by this proposal and
functions such as MACROEXPAND.
[Note: Some modification to this will be required to support Issue
PROCLAIM-LEXICAL if it is adopted. The changes would involve adding a
:LEXICAL keyword similar to :SPECIAL, and fixing up the error signaling
cases.]
ENVIRONMENT-PROPERTY env name property &optional default
This function and its SETF method allow the association of arbitrary 'global'
properties with names within an environment. An environment can be thought
of as having a local property list associated with any name, and this
function provides access to that property list.
A remote environment may be thought of as an extension of the local
environment. Thus, when this function is applied to a remote environment and
the property is not found, the local environment is then searched.
The association between names and property lists uses EQUAL to match names.
The search of the property list uses EQ to match properties. If the property
is not found, DEFAULT is returned.
Using SETF of ENVIRONMENT-PROPERTY affects all environments which refer to
the same environment model. In particular, if ENV is a local environment
then all local environments are affected, while if ENV is a remote
environment, then all environments refering to the same remote environment
model as the argument are affected.
[Note: The local property list of a name is not necessarily the symbol-plist
of the name, though that is a possible implementation for names which are
symbols.
Note: The use of EQUAL as the matching function for names is to allow for
proposed extensions to function names. If no such extension occurs, then EQ
could be used instead.]
WITH-REMOTE-ENVIRONMENT var &body body [Macro]
Evaluates the BODY forms with VAR bound to a newly created remote
environment. The extent of the environment is the dynamic extent of the
WITH-REMOTE-ENVIRONMENT form. Before the extent is exited, each of the
cleanup functions specified by RECORD-ENVIRONMENT-CLEANUP is called with the
environment as its argument. The order in which the cleanup functions are
called is unspecified.
This is the only specified mechanism by which a new remote environment may be
created.
RECORD-ENVIRONMENT-CLEANUP env function [Function]
Record a function to be called when the extent of the environment is exited.
An error of type TYPE-ERROR is signaled if ENV is not a remote environment.
When the extent of ENV ends, FUNCTION will be called with one argument, an
environment which refers to the same remote environment model as the argument
environment.
[Note: The present author does not like the name of this function.
Suggestions solicited.]
MAKE-NULL-ENVIRONMENT &optional env [Function]
Create and return a NULL lexical environment. The ENV argument is used to
determine whether the new environment should be local or remote. If remote,
the two will refer to the same model of the remote environment. The extent
of the returned environment is the same as the extent of the argument.
Rationale:
This proposal provides a portable interface to environment information which
must otherwise be obtained by implementation-dependent means. The
ENSURE-GENERIC-FUNCTION and FIND-CLASS functions of CLOS require the
ENVIRONMENT-REMOTE-P function and some mechanism similar to that supplied by
the ENVIRONMENT-PROPERTY function. A useful code walker requires the
capability of adding local function definitions to an environment.
Making TYPE and FTYPE information optional continues to allow implementations
the freedom to simply ignore all such declarations.
WITH-REMOTE-ENVIRONMENT and RECORD-ENVIRONMENT-CLEANUP provide functionality
which some people believe is needed to implement some of the remote metaobject
mechanisms in CLOS.
MAKE-NULL-ENVIRONMENT is provided for use by code-walkers, so that they can
handle occurances of special-forms like LOAD-TIME-EVAL, which requires a NULL
lexical environment.
Cost to Implementors:
Most implementations already record some of this information in some form.
Providing these functions should not be too difficult, but it is a more than
trivial amount of work.
Cost to Users:
This change is upward compatible with user code.
Current practice:
No implementation provides all of this interface currently. Portable Common
Loops defines a subset of this functionality for its code walker and
implements it on a number of diffent versions of Common Lisp. IIM uses the
functionality provided by ENVIRONMENT-REMOTE-P and ENVIRONMENT-PROPERTY (under
other names) to implement the association between names and remote metaobjects
(macro and type definitions, CLOS remote metaobjects, &etc).
Discussion:
The first version of this proposal expressly did not deal with the objects
which are used as environments by EVALHOOK. This version is extended to
support them in the belief that such environments share a lot of functionality
with the syntactic environments needed by a compiler. While the two types of
environments may have very different implementations, there are many
operations which are reasonable to perform on either type, including all of
the accessor functions described by this proposal.
AUGMENT-ENVIRONMENT currently requires signaling an error when symbol-macro
names match variable names in the same call. This could be reduced to "should
signal". By requiring the error signaling, this proposal is compatable with
Proposal SYMBOL-MACROLET-DECLARE:ALLOW, which says
"... signals an error if a SPECIAL declaration names one of the symbols
being defined as a symbol-macrolet."
Maintaining compatability with the SYMBOL-MACROLET-DECLARE proposal allows
fairly trivial implementations of the SYMBOL-MACROLET special-form in terms of
the AUGMENT-ENVIRONMENT function.
An possible alternative syntax for WITH-REMOTE-ENVIRONMENT might be
WITH-REMOTE-ENVIRONMENT (var &key) &body body
Can anyone suggest candidates for keyword options? We could do this even if
we can't think of any immediately, leaving room for implementation-specific
extensions. One candidate option that some implementations might want would
be to specify a target machine for the compilation.
Kim Barrett originally suggested that WITH-COMPILATION-UNIT should provide the
mechanism for creating new remote environments. However, it has been
suggested that WITH-COMPILATION-UNIT is intended to serve a somewhat different
purpose. Also, that proposal doesn't seem to be getting much attention due to
time constraints, and this proposal needs to have such a mechanism specified.
≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠≠
-------
∂10-Mar-89 0626 CL-Compiler-mailer Re: Issue: LOCALLY-TOP-LEVEL (Version 1)
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 10 Mar 89 06:21:11 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa02326; 10 Mar 89 9:10 EST
Received: from draper.com by RELAY.CS.NET id aa24106; 10 Mar 89 9:03 EST
Date: Fri, 10 Mar 89 08:08 EST
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Re: Issue: LOCALLY-TOP-LEVEL (Version 1)
To: cl-compiler@SAIL.STANFORD.EDU
X-VMS-To: CL-COMPILER,SEB1525
Couldn't LOCALLY be a macro that expands into a MACROLET with a null binding
list (assuming that the body of a MACROLET retains top-level-ness)?
∂10-Mar-89 0836 CL-Compiler-mailer Re: Issue: LOCALLY-TOP-LEVEL (Version 1)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Mar 89 08:36:04 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA23275; Fri, 10 Mar 89 09:33:58 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10605; Fri, 10 Mar 89 09:33:50 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903101633.AA10605@defun.utah.edu>
Date: Fri, 10 Mar 89 09:33:48 MST
Subject: Re: Issue: LOCALLY-TOP-LEVEL (Version 1)
To: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: "Steve Bacher (Batchman)" <SEB1525@draper.com>, Fri, 10 Mar 89 08:08 EST
> Couldn't LOCALLY be a macro that expands into a MACROLET with a null binding
> list (assuming that the body of a MACROLET retains top-level-ness)?
I suppose so, but that would still require a change to so that the standard
would *require* it to expand into a MACROLET (and not a LET or something
else).
-Sandra
-------
∂10-Mar-89 0834 CL-Compiler-mailer Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Mar 89 08:34:30 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA23239; Fri, 10 Mar 89 09:32:24 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10593; Fri, 10 Mar 89 09:32:18 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903101632.AA10593@defun.utah.edu>
Date: Fri, 10 Mar 89 09:32:16 MST
Subject: Re: Issue SYNTACTIC-ENVIRONMENT-ACCESS
To: Kim A. Barrett <IIM@ECLA.USC.EDU>
Cc: cl-compiler@SAIL.STANFORD.EDU
In-Reply-To: Kim A. Barrett <IIM@ECLA.USC.EDU>, Thu 9 Mar 89 23:12:17-PST
Well, this writeup looks better than the last one, but I still don't
think it's quite ready to be voted on yet.
I have some editorial comments on the last paragraph of the problem
description:
> Implementing the FIND-CLASS and ENSURE-GENERIC-FUNCTION functions of CLOS
> requires the ability to distinguish between environments used for compiling to
> a file from those used for processing in-core, such as by EVAL or COMPILE.
> Resolution of the LOAD-TIME-EVAL issue may also require this information.
> This problem has been addressed by the recent cleanup issue
> COMPILE-FILE-ENVIRONMENT. Also, it has proven impossible to write a portable
> code walker in Common Lisp, due to insufficient access to the information
> contained in environments and the inability to augment environments with local
> function definitions.
I'm not sure that saying "CLOS requires" this is entirely accurate.
My impression is that it would be possible to implement the
functionality described in Chapters 1 & 2 without this. It mentions
that an environment object might be used to distinguish between
compile-time and run-time environments, but doesn't specify any
different behavior for the two cases. Perhaps more accurate wording
would be to say "the CLOS meta-object protocol assumes...".
I don't see the connection to LOAD-TIME-EVAL. There's certainly
nothing in the current writeup that depends on users being able to look
at the contents of environment objects.
My understanding was that this issue subsumed issue COMPILE-FILE-ENVIRONMENT.
I'd agree that writing a truly portable code-walker is impossible, but
not for the reason you cite. (The real problem is macros that expand
into nonportable syntax.) How about saying that not having environment
accessors makes it "difficult".
> AUGMENT-ENVIRONMENT env &KEY variable
> special
> symbol-macro
> function
> macro
> type
> ftype [Function]
>
I have a couple of suggestions here.
How about combining the SPECIAL, TYPE, and FTYPE arguments into a
DECLARE argument that takes a list of "decl-spec"s? Breaking them up
requires you to do your own parsing of declarations. This would also
solve the problem of what to do if a LEXICAL declaration is added to
the language.
Also, I'd suggest that the values for the :SYMBOL-MACRO and :MACRO
arguments be supplied in the form of the list that is the CADR of the
SYMBOL-MACROLET or MACROLET form. Maybe this is what you intended,
but it's not clear. Anyway, the rationale for this is that if you
want the :MACRO argument to be real "macro functions", people who
write code walkers would have to write their own macro argument
destructuring code, which is really a pain. Have the implementation
do it.
> ENVIRONMENT-PROPERTY env name property &optional default
I'm still not convinced that we really need this feature. It seems
more like a mechanism that implementations might use internally. I'd
suggest having two proposals: one that includes everything but this,
and one that adds this feature. I don't think "this is needed to
implement CLOS" is a good enough excuse for adding something to the
language. There are lots of things necessary to implement other parts
of the language that we haven't made visible to the user.
> WITH-REMOTE-ENVIRONMENT var &body body [Macro]
>
> RECORD-ENVIRONMENT-CLEANUP env function [Function]
Yuck. Why not use a syntax like unwind-protect?
WITH-REMOTE-ENVIRONMENT var protected-form {cleanup-form}*
> MAKE-NULL-ENVIRONMENT &optional env [Function]
I don't think this function is necessary. When your code walker
encounters a LOAD-TIME-VALUE form, you presumably still have a handle
on the null, remote environment that originally got created with
WITH-REMOTE-ENVIRONMENT. All this function does is retrieve it,
right?
-Sandra
-------
∂10-Mar-89 0916 CL-Cleanup-mailer issue IN-PACKAGE-FUNCTIONALITY, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Mar 89 09:15:59 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA24750; Fri, 10 Mar 89 10:13:52 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10642; Fri, 10 Mar 89 10:13:50 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903101713.AA10642@defun.utah.edu>
Date: Fri, 10 Mar 89 10:13:48 MST
Subject: issue IN-PACKAGE-FUNCTIONALITY, version 7
To: cl-cleanup@sail.stanford.edu
Cc: cl-compiler@sail.stanford.edu
Here's a new version of the writeup for this issue. Since Pitman has
indicated he wants to withdraw the SELECT-ONLY proposal, it has gone
away. I also fixed the typo noted by Moon.
Issue: IN-PACKAGE-FUNCTIONALITY
References: IN-PACKAGE (p182-183)
Category: CHANGE
Edit history: 07-Jul-88, Version 1 by Pitman
7-Oct-88, Version 2 by Masinter (discussion)
8-Dec-88, Version 3 by Masinter
12-Dec-88, Version 4 by Masinter
20-Jan-89, Version 5 by Loosemore
30-Jan-89, Version 6 by Loosemore
10-Mar-89, Version 7 by Loosemore
Related-Issues: DEFPACKAGE (passed)
COMPILE-FILE-SYMBOL-HANDLING
Problem Description:
There are two typical uses for IN-PACKAGE -- to define/create a package
and to select a package. The fact that these two purposes have been
given to the same function has led to reduced error checking.
A more general problem is that the "Put In Seven Extremely Randoms"
convention described in CLtL is now recognized by many people as being
unsatisfactory for both package definition and package selection.
The DEFPACKAGE macro provides a much cleaner mechanism for package
definition, but there is still a need for a convenient way to select
a package that has well-defined compilation semantics.
Proposal (IN-PACKAGE-FUNCTIONALITY:NEW-MACRO):
Add a new macro:
SELECT-PACKAGE name [macro]
This macro causes *PACKAGE* to be set to the package named NAME,
which must be a symbol or string. An error is signalled if the
package does not already exist. Everything this macro does is also
performed at compile time if the call appears at top-level.
Remove the function IN-PACKAGE from the standard.
Remove the second paragraph of section 11.7 in CLtL. (This includes
the requirement for special compile-time treatment of the various
package functions.)
Rationale:
This could allow improved error checking and modularity, with only
minimal loss of functionality.
The rationale for proposing SELECT-PACKAGE as a replacement for
IN-PACKAGE, rather than simply changing IN-PACKAGE to have this
behavior, is that such an incompatible change would be confusing to
many people, and would make it more difficult to detect obsolete
usages. There is nothing in this proposal that would prevent
implementations from continuing to provide IN-PACKAGE as an extension.
Making SELECT-PACKAGE a macro rather than a function means that there
is no need to require COMPILE-FILE to handle it specially. Since
DEFPACKAGE is also defined to side-effect the compilation environment,
there is no need to require any of the package functions to be treated
specially by the compiler.
The language in section 11.7 of CLtL puts the burden on
implementations of ensuring that all symbols in a file which is
compiled and loaded end up in the same package that they would if the
source file were loaded interpretively. No implementation can
possibly meet this requirement because, in general, the runtime
behavior of the program cannot be predicted by the compiler.
Current Practice:
Probably no one implements this behavior exactly since it's an
incompatible change to CLtL.
Cost to Implementors:
The SELECT-PACKAGE macro can be implemented trivially by using
EVAL-WHEN in its expansion:
(defmacro select-package (name)
`(eval-when (eval compile load)
(setq *package*
(or (find-package ',name)
(error "Package ~s does not exist." ',name)))))
The changes required to COMPILE-FILE to remove the magic treatment
of the package functions are also likely to be small.
Cost to Users:
In most cases, minor syntactic changes to some files would be
necessary. Programmers that are now using the "Put In Seven
Extremely Randoms" convention will probably find it straightforward
to convert their code to do a DEFPACKAGE followed by a
SELECT-PACKAGE.
Cost of Non-Adoption:
The specification of COMPILE-FILE will be much more difficult to
understand.
The standard will require compilers to solve the halting problem.
Benefits:
Modular package declarations would be encouraged and errors due
to demand-creation of packages would be easier to detect.
The specification of COMPILE-FILE will be simplified.
There will be a clear statement of the requirements for program
conformance, as relating to usage of packages.
Aesthetics:
The fact that IN-PACKAGE is currently ambiguous about intent (whether
the package should exist already or not) is clearly not aesthetic.
Removing it can't be any worse.
The fact that the currently stated requirements for handling of
the package functions by the compiler are not implementable is
clearly not aesthetic.
Discussion:
The dual use of IN-PACKAGE has not been helpful and is confusing.
Some people may find proposal NEW-MACRO more palatable if it merely
deprecated IN-PACKAGE, instead of removing it entirely.
Loosemore and Moon support proposal IN-PACKAGE-FUNCTIONALITY:NEW-MACRO.
Pitman says:
I support NEW-MACRO, though would really prefer you change "remove" to
"deprecate". Making this an incompatible change is gratuitous.
-------
∂10-Mar-89 1000 CL-Cleanup-mailer issue IN-PACKAGE-FUNCTIONALITY, version 7
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Mar 89 09:59:57 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 554628; 10 Mar 89 12:55:40 EST
Date: Fri, 10 Mar 89 12:55 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue IN-PACKAGE-FUNCTIONALITY, version 7
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: cl-cleanup@sail.stanford.edu, cl-compiler@sail.stanford.edu
In-Reply-To: <8903101713.AA10642@defun.utah.edu>
Message-ID: <19890310175523.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
IN-PACKAGE-FUNCTIONALITY:NEW-MACRO is okay with me.
∂10-Mar-89 1258 Common-Lisp-Object-System-mailer issue CLOS-MACRO-COMPILATION, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Mar 89 12:58:24 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA03202; Fri, 10 Mar 89 13:56:09 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA10809; Fri, 10 Mar 89 13:56:06 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903102056.AA10809@defun.utah.edu>
Date: Fri, 10 Mar 89 13:56:05 MST
Subject: issue CLOS-MACRO-COMPILATION, version 1
To: cl-compiler@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Thu, 9 Mar 89 20:04 EST
Here is a first cut at getting something written down on this issue.
This is mostly extracted from David Gray's list of questions and
Moon's responses. To me it seems like the question where there is the
most disagreement is whether or not classes are required to be
instantiable at compile-time, so I have made two proposals. MINIMAL
leaves this unspecified, and NOT-SO-MINIMAL requires them to be
instantiable.
Forum: Compiler
Issue: CLOS-MACRO-COMPILATION
References: CLOS chapters 1 & 2 (88-002R)
CLOS chapter 3 (89-003)
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CLARIFICATION
Edit History: V1, 10 Mar 1989, Sandra Loosemore
Status: **DRAFT**
Problem Description:
Do the CLOS defining macros (DEFCLASS, DEFMETHOD, DEFGENERIC, and
DEFINE-METHOD-COMBINATION) have compile-time side-effects similar
to those for DEFSTRUCT or DEFMACRO?
A part of the problem is that we do not currently have a full
understanding of all the issues involved. In particular, work on
defining the CLOS meta-object protocol is still in progress. The goal
is to say enough about the behavior of these macros in the standard so
that users can use them portably in compiled code, but to leave as
much of the behavior as possible unspecified to avoid placing undue
restrictions on the meta-object protocol.
There are two proposals, MINIMAL and NOT-SO-MINIMAL.
Proposal CLOS-MACRO-COMPILATION:MINIMAL:
State that top-level calls to the CLOS defining macros have the
following compile-time side-effects. Any other compile-time behavior
is explicitly left unspecified.
DEFCLASS:
* The class name becomes a type specifier which may appear in
subsequent type declarations.
* The class name can be used to name a superclass in a subsequent
DEFCLASS.
* The class name can be used as a specializer in a subsequent
DEFMETHOD.
DEFGENERIC:
* The generic function can be referenced in a subsequent DEFMETHOD.
* The generic function is not callable at compile-time.
DEFMETHOD:
* The method is not callable at compile-time. If there is a generic
function with the same name at compile-time, compiling a DEFMETHOD
will not add the method to that generic function.
[This also seems to imply that tests for existence of the generic
function, lambda-list congruence, etc. must not happen until
load time.]
DEFINE-METHOD-COMBINATION:
* The method combination can be used in a subsequent DEFGENERIC. If it
is referenced, the body of a long form of method combination must be
evaluable at compile-time.
Rationale:
The compile-time behavior of DEFCLASS is similar to DEFSTRUCT or
DEFTYPE. DEFGENERIC and DEFMETHOD are similar to DEFUN.
DEFINE-METHOD-COMBINATION is similar to DEFMACRO or DEFSETF.
Proposal CLOS-MACRO-COMPILATION:NOT-SO-MINIMAL:
This is the same as proposal MINIMAL, except under DEFCLASS add:
* The class may be instantiated at compile-time. Provided the
appropriate methods are also defined at compile-time, this implies:
- The class can be used as the :METACLASS option of a later DEFCLASS.
- It can be used as the :GENERIC-FUNCTION-CLASS or :METHOD-CLASS option
of a DEFGENERIC, GENERIC-FUNCTION, GENERIC-FLET, or GENERIC-LABELS.
Rationale:
Being able to instantiate a class at compile-time is somewhat more
convenient for users.
Current Practice:
The items listed under DEFCLASS in proposal MINIMAL are fairly standard
programming style.
Flavors does not support compile-time instantiation of classes. It
does not make method combinations available at compile-time either, but
Moon considers that to be a bad design choice.
Cost to implementors:
Unknown.
Cost to users:
Unknown, but probably fairly small.
Note that for proposal NOT-SO-MINIMAL, users still have to ensure that
any methods on the class which may be invoked at compile-time are
fully defined. This includes the INITIALIZE-INSTANCE and
SHARED-INITIALIZE methods that are invoked by MAKE-INSTANCE.
Wrapping an (EVAL-WHEN (EVAL COMPILE LOAD) ...) around the appropriate
definitions will make sure they are fully defined at compile-time.
Alternatively, the definitions could be placed in a separate file,
which is loaded before compiling the file that depends on those
definitions.
Benefits:
Programmers can rely on programs that use the CLOS defining macros
being able to compile correctly in all implementations, without having
to wrap explicit EVAL-WHENs around every macro call.
Discussion:
Loosemore says:
Although I admit I don't understand all of the issues involved with
the meta-object protocol, I support proposal MINIMAL. I don't think
leaving the issue of whether or not classes can be instantiated at
compile-time unspecified places an undue burden on users, and it does
leave more freedom for the meta-object protocol to decide what the
right behavior really is.
-------
∂10-Mar-89 1324 CL-Compiler-mailer Issue: DEFINE-OPTIMIZER (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Mar 89 13:24:11 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554754; Fri 10-Mar-89 16:21:48 EST
Date: Fri, 10 Mar 89 16:21 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: DEFINE-OPTIMIZER (Version 2)
To: CL-Compiler@SAIL.Stanford.EDU
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <890310162127.0.KMP@BOBOLINK.SCRC.Symbolics.COM>
Most of the discussion which came from the previous draft came from the
following two points:
1. Some people were very confused by the use of STRING-APPEND as an
example, apparently because so many implementations offer
STRING-APPEND as an extension that everyone thought I was suggesting
that users could and should write optimizers for CL built-in functions,
something which I don't think is a good idea.
2. Some people wanted a pattern matching facility intertwined with this.
I addressed these problems in the following ways:
1. I removed the STRING-APPEND example and replaced it with a couple
of small examples taken directly from the Common Lisp Macsyma (R)
sources, since it was Macsyma that motivated this issue in the first
place. Macsyma actually has some considerably more elaborate
optimizers, but it would have been a lot more trouble for me to get
someone to authorize me to release the sources for them than for
these simple examples, so I hope these will suffice.
2. I added a note to the Discussion mentioning that this was a nice idea,
but that we don't have time to develop such a thing. However, as I
hope the examples illustrate, there is still quite a bit that can be
done even with the simpler facility proposed here, and I hope people
will seriously consider this without getting bogged down in a bunch
of really orthogonal issues.
-----
Issue: DEFINE-OPTIMIZER
References: None
Category: ADDITION
Edit history: 28-Sep-88, Version 1 by Pitman
10-Mar-89, Version 2 by Pitman (clarifications, new example)
Status: For Internal Discussion
Problem Description:
Often a general functional interface could be bypassed given explicit
knowledge of the arguments passed. This may happen when the arguments
are constant (or otherwise inferrable), an argument type is known (eg,
due to use of THE or DECLARE), or when some particular pattern of
optional, rest or keyword arguments is apparent.
Most implementations provide internally for optimization of generalized
function call interfaces to more specialized ones, but such an
optimization facility is not provided to Common Lisp users.
The absence of this facility in a portable fashion means that some
CL programs run slower than they need to in some implementations.
Proposal (DEFINE-OPTIMIZER:NEW-FACILITY):
Introduce a facility for declaring compiler optimizations.
DEFINE-OPTIMIZER name arglist &body forms
Defines a compiler optimizer for a function named NAME. The arglist
is treated exactly like the arglist to DEFMACRO, and may include
&ENVIRONMENT and &WHOLE.
When the optimizer is invoked, the forms are executed in the context
of bindings specified by the arglist, and two values are yielded,
RESULT and VALID-P. (If either of the first or second return value
is non-NIL, then the first return value is considered valid).
If the result is valid, it is a form which is preferrable to evaluate
instead of the indicated call.
OPTIMIZE-EXPRESSION-1 form env
Similar to MACROEXPAND-1. Invokes the optimizers for the top level of
FORM, but does not iterate on the result. Returns two values:
RESULT and CHANGED-P.
Note: If an optimizer returns a result which is not valid,
OPTIMIZE-EXPRESSION-1 hides the fact by returning FORM,NIL
rather than NIL,NIL.
OPTIMIZE-EXPRESSION form env
Iterates calling OPTIMIZE-EXPRESSION-1 until the CHANGED-P result
is NIL.
An implementation must save optimizer definitions created by
DEFINE-OPTIMIZER in case OPTIMIZE-EXPRESSION is attempted, but is
not actually required to call OPTIMIZE-EXPRESSION itself. Interpreters,
for example, may choose to just call the unoptimized form.
The effect of defining optimizations for functions on the LISP package
is not defined. (In some implementations, this would clobber or conflict
with existing advice that may be of higher quality.)
The editor is advised that a non-binding style note such as the
following would also be appropriate:
In general, it is poor style for a programmer to define optimizers for
functions that he does not maintain. This is because the correct
implementation of an optimizer for a function usually depends on an
understanding of the internals of that function. As such, a function
definition and any optimizers should be maintained as a unit so that
they can changes in either can be synchronized as appropriate with the
other.
Example:
;; These examples are taken literally from the Macsyma sources,
;; modified only to change DEFOPT to DEFINE-OPTIMIZER. The comments
;; were specially written for the X3J13 audience.
;; M+ is adds a Macsyma expression to another Macsyma expression.
;; The Macsyma internal representation for the sum of X and Y is
;; ((MPLUS) X Y). A all the real work is done by SIMPLIFY, which
;; reduces the expression as needed necessary. However, SIMPLIFY
;; is very complicated, and considerable speed can be gained by
;; entering it at specific known places.
(DEFUN M+ (&REST TERMS)
(PROTECT-&REST-VARIABLE TERMS)
(SIMPLIFY `((MPLUS) ,@TERMS)))
(DEFOPT M+ (&REST TERMS)
(COND ((= (LENGTH TERMS) 2) `(ADD2* ,@TERMS))
(T `(ADDN (LIST ,@TERMS) NIL))))
;; M- negates a Macsyma expression, or substracts two Macsyma
;; expressions. Once you figure out which of the two operations is
;; to be done, the problem is similar to that of M+ above. However,
;; often the decision can be made at compile time. In this case,
;; INLINE functions would have worked ok, except that not all
;; implementations do inlining, and even those that do may fail to
;; recognize that EXP2 being NIL means that a test can be eliminated
;; or dead code can be eliminated. Using optimizers is far more
;; likely to be useful in practice.
(DEFUN M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
(M--INTERNAL-NEGATE EXP1)
(M--INTERNAL-SUBTRACT EXP1 EXP2)))
(DEFOPT M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
`(M--INTERNAL-NEGATE ,EXP1)
`(M--INTERNAL-SUBTRACT ,EXP1 ,EXP2)))
Rationale:
Many large portable applications expect such a facility on an
implementation-specific basis. Others would use one if available.
Even if implementations don't use the provided optimizers primitively,
user macros and code-walkers can invoke them, so the facility wouldn't
be completely useless even in those implementations.
Current Practice:
Symbolics Genera provides an optimizer facility which is more elaborate
but not fundamentally incompatible with this facility.
Many (if not most) serious implementations provide a similar facility.
Cost to Implementors:
Since the implementation is not required to use this facility, the
cost of providing the proposed support is very small.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Portable code would be slower than necessary in some situations.
Benefits:
Some existing non-portable code could become portable.
Aesthetics:
Providing a separate optimizer definition from a main function definition
makes a possibility that the optimizer and main function could drift out
of synch. However, most places where this gets used in the first place
are places where speed is of paramount importance and the programmer is
willing to invest effort in maintaining things correctly and to accept the
risk of lossage if s/he fails.
This is a fairly clean and simple extension which adds significant
power to the compiler.
Discussion:
Pitman strongly supports this proposal, the design of which is modeled
directly after that which has been used in Macsyma for many years.
Information about argument type can come from two different sources:
THE and declarations (via PROCLAIM or DECLARE). The former information
is portably accessible, the latter is not. While a separate proposal
for allowing program access to type declarations would be make this
facility more useful, it is still quite useful without it, as the
examples from Macsyma illustrate.
Some implementations provide a way to provide more than one optimizer
for the same function. A multiple optimizer facility can be written
in terms of this simpler facility and vice versa, so the simpler of
the two facilities is proposed here.
Some people have suggested that they would like to see a pattern
matching facility integrated into this facility. The design of a
facility that would satisfy everyone would take a lot of time and
effort. At this point, there is no chance that the design of such a
facility would occur in time for acceptance into the standard.
The choice is this or nothing. Pitman thinks the language is much
better off with some form of optimization support than none.
∂10-Mar-89 1407 CL-Compiler-mailer Issue: WITH-COMPILATION-UNIT (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Mar 89 14:07:20 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554788; Fri 10-Mar-89 17:04:58 EST
Date: Fri, 10 Mar 89 17:04 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: WITH-COMPILATION-UNIT (Version 2)
To: CL-Compiler@SAIL.Stanford.EDU
Message-ID: <890310170444.1.KMP@BOBOLINK.SCRC.Symbolics.COM>
I read back over the mail related to this and most of it was centered
around extensions that we might want to do. I think we can't really
consider most of those extensions at this point because it's too late in
the game.
Basically, I merged the few comments that were easy to do without
disturbing the simple nature of the proposal.
I think, however, that if we can just get behind this straightforward,
extensible proposal, there will be a good framework in place for
extending it in some subsequent standard after individual
implementations have had time to experiment a bit with the paradigm.
-----
Issue: WITH-COMPILATION-UNIT
References: COMPILE (p438), COMPILE-FILE (p439)
Category: ADDITION
Edit history: 29-Sep-88, Version 1 by Pitman
10-Mar-89, Version 2 by Pitman (merge comments)
Status: For Internal Discussion
Problem Description:
Some actions done by the compiler (and particularly the file compiler)
are typically deferred until the "very end" of compilation. For example,
some compilers complain about "functions seen but not defined".
Unfortunately, since COMPILE-FILE is the largest unit of granularity,
and since systems often extend over more than one file, it often happens
that the compiler needlessly complains at the end of compiling one file
about the absence of functions defined in the next file.
Proposal (WITH-COMPILATION-UNIT:NEW-MACRO):
Add the following new macro:
WITH-COMPILATION-UNIT options &BODY forms [Macro]
Executes forms from left to right. Within the dynamic context
of this form, actions deferred by the compiler until "the end of
compilation" will be deferred until the end of the outermost call
to WITH-COMPILATION-UNIT. The result(s) are the same as that of
the last of the FORMS (or NIL if FORMS is null).
OPTIONS is a keyword/value list, where only the values are
evaluated. The set of keywords permitted may be extended by the
implementation, but the only keyword defined by this standard is:
:OVERRIDE boolean
The default is NIL. If nested dynamically only the outer call
to WITH-COMPILATION-UNIT has any effect unless BOOLEAN is T,
in which case warnings are deferred only to the end of the
innermost call.
It follows that the functions COMPILE and COMPILE-FILE should
provide the effect of (WITH-COMPILATION-UNIT (:OVERRIDE NIL) ...)
around their code.
Note also that not all warnings are deferred. In some implementations,
it may be that none are deferred. This proposal only creates an
interface to the capability where it exists, it does not require the
creation of the capability. An implementation which does not do
deferred warnings may correctly implement this as expanding into PROGN.
Test Case:
(DEFUN COMPILE-FILES (&REST FILES)
(WITH-COMPILATION-UNIT ()
(MAPCAR #'(LAMBDA (FILE) (COMPILE-FILE FILE)) FILES)))
(COMPILE-FILES "A" "B" "C")
processes deferred warnings only after compiling all of A, B, and C.
Rationale:
This will make the development of portable system-construction tools
considerably more convenient.
Current Practice:
Lucid has a very similar facility, called WITH-DEFERRED-WARNINGS.
TI Explorer and Symbolics Genera have a similar facility, which they
call COMPILER-WARNING-CONTEXT-BIND.
Cost to Implementors:
In implementations which have no deferred warnings, there is no cost.
In implementations which have deferred warnings, the cost is probably
fairly small -- usually just a matter of writing interfacing the
proposed macro to an existing one.
Cost to Users:
None. This is a compatible addition.
Cost of Non-Adoption:
Portable system-construction tools would continue to print lots of
spurious warnings because they would have no way to tell the system
that a set of files was working together.
Benefits:
The cost of non-adoption is avoided.
Aesthetics:
The ability to create a compilation unit other than a file is important.
Discussion:
Pitman and Benson support this addition.
One could imagine adding more options at a later date.
It was the opinion of the compiler committee that there was room for
expansion here to address issues like bounding the scope of global
proclamations, sharing compile-time environments across files, etc.
However, insufficient work was done on this to justify putting such
a thing into the standard. The only clear need we have at this time
was to defer warnings, but we chose a general name like
WITH-COMPILATION-UNIT rather than a specific name like Lucid's
WITH-DEFERRED-WARNINGS in order to encourage implementations to
experiment with other kinds of options under implementation-specific
keywords. Perhaps by the time of the next standard there will be
sufficient understanding of this area to warrant further elaboration
of this primitive.
∂10-Mar-89 1525 CL-Compiler-mailer Re: Issue: DEFINE-OPTIMIZER (Version 2)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Mar 89 15:25:21 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA11643; Fri, 10 Mar 89 16:22:57 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA11082; Fri, 10 Mar 89 16:22:55 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903102322.AA11082@defun.utah.edu>
Date: Fri, 10 Mar 89 16:22:53 MST
Subject: Re: Issue: DEFINE-OPTIMIZER (Version 2)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 10 Mar 89 16:21 EST
This is looking better, but I personally would still want to see
a few things clarified before I could vote for it.
o Can you put declarations in the body? I don't see any reason why not,
except that the writeup doesn't say so.
o Can you define an optimizer for a macro as well as a function? (If it
were permitted, it might make the interaction between OPTIMIZE-EXPRESSION
and MACROEXPAND kind of confusing.)
o I don't think OPTIMIZE-EXPRESSION-1 should apply an optimizer that
has been defined for a function that is lexically shadowed (as by
an FLET or MACROLET) in the environment. Can we say something
specific about what happen in this situation, one way or the other?
Otherwise, I think the basic idea is fine.
-Sandra
-------
∂10-Mar-89 1556 CL-Compiler-mailer Re: Issue: WITH-COMPILATION-UNIT (Version 2)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Mar 89 15:56:12 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA12911; Fri, 10 Mar 89 16:54:00 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA11110; Fri, 10 Mar 89 16:53:29 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903102353.AA11110@defun.utah.edu>
Date: Fri, 10 Mar 89 16:53:27 MST
Subject: Re: Issue: WITH-COMPILATION-UNIT (Version 2)
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Cc: CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>, Fri, 10 Mar 89 17:04 EST
This looks generally OK. One question I have is whether
implementations may extend this construct to do things other than
handle deferred warnings, without requiring the user to explicitly
provide an option to get that behavior. (Sharing of compilation
environments is a good example.)
As an editorial nit, I'd like to see something in the proposal itself
to indicate that the purpose of WITH-COMPILATION-UNIT is more general
than just causing warnings to be deferred. This really goes
hand-in-hand with the above -- if we say that the purpose of
WITH-COMPILATION-UNIT is to tell the compiler that it should treat
multiple calls as relating to the same module or unit, then I think it
would be OK for an implementation to do other things as well. On the
other hand, if we say that the purpose is only to defer warnings, then
the only thing it should do by default is defer warnings.
-Sandra
-------
∂10-Mar-89 1553 CL-Cleanup-mailer Re: issue IN-PACKAGE-FUNCTIONALITY, version 7
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 10 Mar 89 15:53:15 PST
Received: from Semillon.ms by ArpaGateway.ms ; 10 MAR 89 15:50:29 PST
Date: 10 Mar 89 15:49 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue IN-PACKAGE-FUNCTIONALITY, version 7
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message
of Fri, 10 Mar 89 12:55 EST
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>,
cl-cleanup@sail.stanford.edu, cl-compiler@sail.stanford.edu
Message-ID: <890310-155029-16287@Xerox>
maybe I'm late, but I still liked SELECT-ONLY better than NEW-MACRO. Just
to calibrate, I didn't like removing REQUIRE & PROVIDE, either.
∂10-Mar-89 1615 CL-Compiler-mailer Re: Issue: WITH-COMPILATION-UNIT (Version 2)
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 10 Mar 89 16:15:44 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 280423; Fri 10-Mar-89 19:12:36 EST
Date: Fri, 10 Mar 89 19:12 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: WITH-COMPILATION-UNIT (Version 2)
To: Sandra%defun@cs.utah.edu
cc: CL-Compiler@SAIL.Stanford.EDU
In-Reply-To: <8903102353.AA11110@defun.utah.edu>
Message-ID: <890310191241.7.KMP@BOBOLINK.SCRC.Symbolics.COM>
My belief was that if it does anything other than defer warnings without
your having to ask it to (using keywords), then portability would
be sacrificed because it may have radically different effects in
each implementation. On the next standardization, we can talk
about not only adding options, but allowing them to default.
I guess it should say in the Proposal part:
Any implementation-dependent extensions may only be provided
as the result of an explicit programmer request by use of
an implementation-dependent keyword. Implementations are forbidden
from attaching additional meaning to a conforming use of this
macro.
If we just said that, would that alleviate the need for further examples?
∂10-Mar-89 1730 CL-Compiler-mailer issue DEFINE-OPTIMIZER, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 10 Mar 89 17:29:53 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA14983; Fri, 10 Mar 89 18:27:46 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA11236; Fri, 10 Mar 89 18:27:41 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903110127.AA11236@defun.utah.edu>
Date: Fri, 10 Mar 89 18:27:40 MST
Subject: issue DEFINE-OPTIMIZER, version 3
To: cl-compiler@sail.stanford.edu
Kent and I have given this one another iteration to fix the
ambiguities. Hopefully we've caught all the bugs this time.
Forum: Compiler
Issue: DEFINE-OPTIMIZER
References: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Category: ADDITION
Edit history: 28-Sep-88, Version 1 by Pitman
10-Mar-89, Version 2 by Pitman (clarifications, new example),
10-Mar-89, Version 3 by Pitman & Loosemore
Status: Ready for release
Problem Description:
Often a general functional interface could be bypassed given explicit
knowledge of the arguments passed. This may happen when the arguments
are constant (or otherwise inferrable), an argument type is known (eg,
due to use of THE or DECLARE), or when some particular pattern of
optional, rest or keyword arguments is apparent.
Most implementations provide internally for optimization of generalized
function call interfaces to more specialized ones, but such an
optimization facility is not provided to Common Lisp users.
The absence of this facility in a portable fashion means that some
CL programs run slower than they need to in some implementations.
Proposal (DEFINE-OPTIMIZER:NEW-FACILITY):
Introduce a facility for declaring compiler optimizations.
DEFINE-OPTIMIZER name arglist {declaration}* {form}* [Macro]
Defines a compiler optimizer for a function named NAME. The ARGLIST,
DECLARATIONS, and FORMS are treated exactly like the arglist,
declarations, and forms in a DEFMACRO. (The arglist may include
&ENVIRONMENT and &WHOLE.)
The argument NAME must name a function which has been previously
defined. The effects of defining an optimizer for a locally or
globally defined macro, a locally defined function, or a special
form are undefined.
When the optimizer is invoked, the forms are executed in the context
of bindings specified by the arglist, and two values are yielded,
RESULT and VALID-P. (If either of the first or second return value
is non-NIL, then the first return value is considered valid).
If the result is valid, it is a form which is preferrable to evaluate
instead of the indicated call.
If a call to DEFINE-OPTIMIZER appears at top-level in a file
being processed by the file compiler, it also makes the optimizer
known at compile-time (similar to the way DEFMACRO makes a macro
definition known to the compiler).
OPTIMIZE-EXPRESSION-1 form env [Function]
Similar to MACROEXPAND-1. Invokes the optimizers for the top level of
FORM, but does not iterate on the result. Returns two values:
RESULT and CHANGED-P.
Note: If an optimizer returns a result which is not valid,
OPTIMIZE-EXPRESSION-1 hides the fact by returning FORM,NIL
rather than NIL,NIL.
OPTIMIZE-EXPRESSION form env [Function]
Iterates calling OPTIMIZE-EXPRESSION-1 until the CHANGED-P result
is NIL.
An implementation must save optimizer definitions created by
DEFINE-OPTIMIZER in case OPTIMIZE-EXPRESSION is attempted, but is
not actually required to call OPTIMIZE-EXPRESSION itself. Interpreters,
for example, may choose to just call the unoptimized form.
Using FLET and MACROLET shadow not only functions and their SETF methods,
but also their optimizers. No portable facility is provided for creating
locally defined optimizers.
The effect of defining optimizations for functions on the LISP package
is not defined. (In some implementations, this would clobber or conflict
with existing advice that may be of higher quality.)
The editor is advised that a non-binding style note such as the
following would also be appropriate:
In general, it is poor style for a programmer to define optimizers for
functions that he does not maintain. This is because the correct
implementation of an optimizer for a function usually depends on an
understanding of the internals of that function. As such, a function
definition and any optimizers should be maintained as a unit so that
they can changes in either can be synchronized as appropriate with the
other.
Example:
;; These examples are taken literally from the Macsyma sources,
;; modified only to change DEFOPT to DEFINE-OPTIMIZER. The comments
;; were specially written for the X3J13 audience.
;; M+ is adds a Macsyma expression to another Macsyma expression.
;; The Macsyma internal representation for the sum of X and Y is
;; ((MPLUS) X Y). A all the real work is done by SIMPLIFY, which
;; reduces the expression as needed necessary. However, SIMPLIFY
;; is very complicated, and considerable speed can be gained by
;; entering it at specific known places.
(DEFUN M+ (&REST TERMS)
(PROTECT-&REST-VARIABLE TERMS)
(SIMPLIFY `((MPLUS) ,@TERMS)))
(DEFINE-OPTIMIZER M+ (&REST TERMS)
(COND ((= (LENGTH TERMS) 2) `(ADD2* ,@TERMS))
(T `(ADDN (LIST ,@TERMS) NIL))))
;; M- negates a Macsyma expression, or substracts two Macsyma
;; expressions. Once you figure out which of the two operations is
;; to be done, the problem is similar to that of M+ above. However,
;; often the decision can be made at compile time. In this case,
;; INLINE functions would have worked ok, except that not all
;; implementations do inlining, and even those that do may fail to
;; recognize that EXP2 being NIL means that a test can be eliminated
;; or dead code can be eliminated. Using optimizers is far more
;; likely to be useful in practice.
(DEFUN M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
(M--INTERNAL-NEGATE EXP1)
(M--INTERNAL-SUBTRACT EXP1 EXP2)))
(DEFINE-OPTIMIZER M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
`(M--INTERNAL-NEGATE ,EXP1)
`(M--INTERNAL-SUBTRACT ,EXP1 ,EXP2)))
Rationale:
Many large portable applications expect such a facility on an
implementation-specific basis. Others would use one if available.
Even if implementations don't use the provided optimizers primitively,
user macros and code-walkers can invoke them, so the facility wouldn't
be completely useless even in those implementations.
Current Practice:
Symbolics Genera provides an optimizer facility which is more elaborate
but not fundamentally incompatible with this facility.
Many (if not most) serious implementations provide a similar facility.
For example, Lucid provides "compiler macros" which serve the same
purpose.
Cost to Implementors:
Since the implementation is not required to use this facility, the
cost of providing the proposed support is very small.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Portable code would be slower than necessary in some situations.
Benefits:
Some existing non-portable code could become portable.
Aesthetics:
Providing a separate optimizer definition from a main function definition
makes a possibility that the optimizer and main function could drift out
of synch. However, most places where this gets used in the first place
are places where speed is of paramount importance and the programmer is
willing to invest effort in maintaining things correctly and to accept the
risk of lossage if s/he fails.
This is a fairly clean and simple extension which adds significant
power to the compiler.
Discussion:
Pitman strongly supports this proposal, the design of which is modeled
directly after that which has been used in Macsyma for many years.
Information about argument type can come from two different sources:
THE and declarations (via PROCLAIM or DECLARE). The former information
is portably accessible, the latter is not. While a separate proposal
(SYNTACTIC-ENVIRONMENT-ACCESS) for allowing program access to type
declarations would be make this facility more useful, it is still
quite useful without it, as the examples from Macsyma illustrate.
Some implementations provide a way to provide more than one optimizer
for the same function. A multiple optimizer facility can be written
in terms of this simpler facility and vice versa, so the simpler of
the two facilities is proposed here.
Some people have suggested that they would like to see a pattern
matching facility integrated into this facility. The design of a
facility that would satisfy everyone would take a lot of time and
effort. At this point, there is no chance that the design of such a
facility would occur in time for acceptance into the standard.
The choice is this or nothing. Pitman thinks the language is much
better off with some form of optimization support than none.
Loosemore says:
Although I don't really think this is an essential feature to include
in the standard, I don't have any strong objection to adding it. If
people think it's a good idea to provide a standard interface for this
kind of thing, this is a good proposal for doing it -- it's fairly
simple, doesn't introduce any radically new ideas, and is general
enough to allow alternate interfaces (such as the pattern matcher) to
be layered on top of it.
-------
∂11-Mar-89 0126 Common-Lisp-Object-System-mailer Re: issue CLOS-MACRO-COMPILATION, version 1
Received: from ti.com by SAIL.Stanford.EDU with TCP; 11 Mar 89 01:25:50 PST
Received: by ti.com id AA05982; Fri, 10 Mar 89 18:21:46 CST
Received: from Kelvin by tilde id AA27610; Fri, 10 Mar 89 18:07:29 CST
Message-Id: <2814566813-5018117@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 10 Mar 89 18:06:53 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
Subject: Re: issue CLOS-MACRO-COMPILATION, version 1
In-Reply-To: Msg of Fri, 10 Mar 89 13:56:05 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Proposal CLOS-MACRO-COMPILATION:MINIMAL:
...
> DEFMETHOD:
>
> * The method is not callable at compile-time. If there is a generic
> function with the same name at compile-time, compiling a DEFMETHOD
> will not add the method to that generic function.
>
> [This also seems to imply that tests for existence of the generic
> function, lambda-list congruence, etc. must not happen until
> load time.]
No, an implementation should be permitted to check for lambda-list
congruence between methods defined in the same file; this doesn't
require any reference to the resident generic function definition. If
the file doesn't include a DEFGENERIC, then the first DEFMETHOD defines
the compile-time generic function attributes, and subsequent methods can
be checked against that.
> DEFINE-METHOD-COMBINATION:
>
> * The method combination can be used in a subsequent DEFGENERIC. If it
> is referenced, the body of a long form of method combination must be
> evaluable at compile-time.
But if methods are not installed at compile time and generic functions
are not callable at compile time, then I don't think there is any
situation in which the method combination body could be executed at
compile-time.
∂11-Mar-89 0152 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
Received: from ti.com by SAIL.Stanford.EDU with TCP; 11 Mar 89 01:51:05 PST
Received: by ti.com id AA04610; Fri, 10 Mar 89 11:48:18 CST
Received: from Kelvin by tilde id AA18376; Fri, 10 Mar 89 11:31:11 CST
Message-Id: <2814543045-3466116@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 10 Mar 89 11:30:45 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu,
"David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>,
"Kim A. Barrett" <IIM%ECLA@ECLC.USC.EDU>
Subject: Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
In-Reply-To: Msg of Thu, 9 Mar 89 15:18:33 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
I think there are still too many unresolved relationships for this issue to
be ready for voting. We have talked about using environments for three
different things, each of which has different implementation
considerations that affect the extent:
1. Macro definitions
If this were all that environments were used for, then proposal
MACRO-ENVIRONMENT-EXTENT:INDEFINITE would be fine.
2. Information about current variable bindings, local functions, type
declarations, and OPTIMIZE declarations (as in issue
SYNTACTIC-ENVIRONMENT-ACCESS).
I don't want to have to support access to this information from a
saved environment object after the compiler has moved on to a
different lexical scope. Proposal
MACRO-ENVIRONMENT-EXTENT:DYNAMIC would solve that, but is more
restrictive than it needs to be.
3. Class definitions.
For these, we want the extent to end at the conclusion of
COMPILE-FILE. Again, proposal MACRO-ENVIRONMENT-EXTENT:DYNAMIC is
much more restrictive than necessary.
I have been talking here about the semantic meaningfulness of the
environments, but there is an orthogonal issue of data representation. If
the concern is that the environment could be a stack list which physically
no longer exists outside its dynamic extent, then proposal
MACRO-ENVIRONMENT-EXTENT:DYNAMIC-WITH-COPIER makes sense as a way to copy
the list to the heap. The copier does not appear to be useful for
addressing the questions of semantic extent above.
How about the following:
Proposal MACRO-ENVIRONMENT-EXTENT:EXTENDED-DYNAMIC-WITH-COPIER:
State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or with a *MACROEXPAND-HOOK* function
have only dynamic extent; the consequences are undefined if they are
referred to outside the dynamic extent of that macro function or hook
function.
Add a new function:
COPY-ENVIRONMENT environment [function]
This function returns an environment object that is semantically
equivalent to "environment" (which must be an object of the type
received with an &ENVIRONMENT argument to a macro or as an argument to
a *MACROEXPAND-HOOK* function), but which may safely be referred to
outside the dynamic extent of the macro function. This function is
permitted to return an object that is EQ to its argument if that
object may be safely used.
The meaningfulness of the copied environment is still subject to the
limitation that it can't be used to access information after the processor
which created the environment (such as a compiler or interpreter) is no
longer processing within the scope of that information. Thus, the
environment can be used in a macro expansion, since the expansion will be
processed in the same lexical scope. Declarations, variable bindings, and
local function and macro definitions [assuming passage of proposal
SYNTACTIC-ENVIRONMENT-ACCESS] can not be reliably accessed at a later
time. Within COMPILE-FILE, class definitions resulting from a top-level
DEFCLASS can not be accessed after processing of the file is complete.
Rationale:
This allows implementations to use somewhat more efficient techniques
for representing environment objects. For example, the storage could
be stack-allocated, or environments could be bashed destructively
instead of always being freshly heap-allocated.
It also allows programmers to use idioms that rely on using environment
objects outside of the macro expander, while defining limitations on the
usable extent of that information. These semantic limitations provide
flexibility in how the implementation actually represents environments,
which is important for minimizing the need to change existing
implementations.
∂11-Mar-89 0200 CL-Compiler-mailer Re: Issue: DEFINE-OPTIMIZER (Version 2)
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 11 Mar 89 02:00:50 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA11684; Sat, 11 Mar 89 02:01:37 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA24334; Fri, 10 Mar 89 14:31:38 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA15806; Fri, 10 Mar 89 14:35:06 PST
Date: Fri, 10 Mar 89 14:35:06 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903102235.AA15806@clam.sun.com>
To: CL-Compiler@SAIL.Stanford.EDU, KMP@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: Issue: DEFINE-OPTIMIZER (Version 2)
Optimizers are important in my experience also. In fact, I would
have sat down on Saturday to write a similar proposal had Kent
not distributed this one.
I support Kent's proposal, with the following suggestions:
An additional function that corresponds to MACRO-FUNCTION for ordinary
macros. I include the proposed definition for this, which follows the
definition of MACRO-FUNCTION in CLtL, p144. This provides
primitive-level access, including the ability to undefine an
optimizer.
Add to the problem description that sometimes an "operator" is defined
as a macro purely because its performance would be inadequate if
implemented as a function.
Also, I believe it would be best to state that in environments where
the compiler is prohibited from treating a function as INLINE,
optimizers are deactivated. In particular, the functions
OPTIMIZE-EXPRESSION and OPTIMIZE-EXPRESSION-1 do not transform their
expression argument if given an environment in which the function must
not be treated as INLINE. (I recognize that this is a bit of
a judgment call.)
The point here is to make user-defined optimizers follow the behavior
of optimizers built-in to compilers in their response to NOTINLINE.
OPTIMIZER-FUNCTION symbol
This function corresponds directly to MACRO-FUNCTION for macros.
The argument must be a symbol. If the symbol has an optimizer
defined, then the optimizer function is returned. An optimizer
function takes two arguments, the expression that may be
optimized and an environment of the same kind accepted by macro
expansion functions. If the symbol has no optimizer, then NIL is
returned.
SETF may be used with OPTIMIZER-FUNCTION to install or change an
optimizer. If NIL is given as the new value, any existing optimizer
definition is removed.
∂11-Mar-89 0150 Common-Lisp-Object-System-mailer Re: Issue MACRO-ENVIRONMENT-EXTENT
Received: from ti.com by SAIL.Stanford.EDU with TCP; 11 Mar 89 01:48:49 PST
Received: by ti.com id AA04514; Fri, 10 Mar 89 11:03:22 CST
Received: from Kelvin by tilde id AA17547; Fri, 10 Mar 89 10:49:22 CST
Message-Id: <2814540528-3314903@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Fri, 10 Mar 89 10:48:48 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: "Kim A. Barrett" <IIM%ECLA@ECLC.USC.EDU>, sandra%defun@CS.UTAH.EDU,
cl-compiler@SAIL.STANFORD.EDU,
common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Issue MACRO-ENVIRONMENT-EXTENT
In-Reply-To: Msg of Thu, 9 Mar 89 13:59 EST from David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
> The extent of macro environment objects is related to EVAL-WHEN because macro
> expanders may wish to return forms which contain environments as quoted
> constants.
>
> I am convinced that this should be ruled out, and that CLOS made a mistake
> here. (Incidentally the part of CLOS that says this is in chapter 3, the
> accepted part of CLOS does not say anything about the expansion of the
> macros is.)
Except for ENSURE-GENERIC-FUNCTION, which is defined in chapter 2 with an
:ENVIRONMENT argument, and referenced on page 2-28 as part of the
semantics of DEFGENERIC. Maybe this function should have been in chapter
3 instead? Should it be removed from the standard?
> Requiring environments to have indefinite extent has
> problems for CLOS because at compile-time it wants to create remote metaobjects
> and link them into the right places, but then flush those links when the
> compilation is over.
>
> This depends on whether you think the environment actually contains the
> table that relates names to objects, or just contains a boolean flag
> that tells functions such as FIND-CLASS which of two tables to look in.
> Under the latter model, nothing about the environment prevents the
> COMPILE-FILE table from being reset at any time. This is one reason
> why I think the second model is right.
But if you reset the table, then a FIND-CLASS on that environment will no
longer be meaningful, which has the same effect as being outside the valid
extent of the environment.
∂11-Mar-89 0810 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Mar 89 08:09:16 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA03663; Sat, 11 Mar 89 09:05:03 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00528; Sat, 11 Mar 89 09:03:44 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903111603.AA00528@defun.utah.edu>
Date: Sat, 11 Mar 89 09:03:42 MST
Subject: Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu,
"David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>,
"Kim A. Barrett" <IIM%ECLA@ECLC.USC.EDU>
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Fri, 10 Mar 89 11:30:45 CST
> Date: Fri, 10 Mar 89 11:30:45 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> Proposal MACRO-ENVIRONMENT-EXTENT:EXTENDED-DYNAMIC-WITH-COPIER:
>
> [...]
>
> The meaningfulness of the copied environment is still subject to the
> limitation that it can't be used to access information after the processor
> which created the environment (such as a compiler or interpreter) is no
> longer processing within the scope of that information. Thus, the
> environment can be used in a macro expansion, since the expansion will be
> processed in the same lexical scope. Declarations, variable bindings, and
> local function and macro definitions [assuming passage of proposal
> SYNTACTIC-ENVIRONMENT-ACCESS] can not be reliably accessed at a later
> time.
This is too vague. What does "scope of that information" mean? Dynamic
scope? Lexical scope? You need to say what the *extent* is, not the
scope.
An example may clarify my confusion. :-) Suppose I'm using
LOCAL-TYPE-DECLARE as implemented in the writeup (but with
COPY-ENVIRONMENT added to it, of course), and then I say something
like:
(defun f (x)
(local-type-declare ((x fixnum))
#'(lambda (y)
(local-type-declare ((y fixnum))
(+ (typed var x) y)))
))
Is this legitimate? Let's assume that the interpreter doesn't do a
code walk. The closure returned when you call F has indefinite
extent, yet it contains a reference to the environment established by
the lexically enclosing LOCAL-TYPE-DECLARE. So if this is legal,
the environment has to have indefinite extent too.
Rather than trying to add all these ill-defined qualifications and
restrictions, if we absolutely cannot agree to give environments
indefinite extent (or to provide a copier to give them indefinite
extent), I would much rather see a simple statement that you can't
assume more than dynamic extent.
> Within COMPILE-FILE, class definitions resulting from a top-level
> DEFCLASS can not be accessed after processing of the file is complete.
As far as I've been able to tell, there is nothing in CLOS chapters 1
& 2 that says that DEFCLASS *must* store class definitions in any
particular way that involves environment objects. I think it would be
premature to say anything about this here until the meta-object protocol
settles down. Also, we don't have any similar restrictions on DEFMACRO
or whatever.
-Sandra
-------
∂11-Mar-89 0818 Common-Lisp-Object-System-mailer Re: issue CLOS-MACRO-COMPILATION, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Mar 89 08:17:53 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA03974; Sat, 11 Mar 89 09:15:41 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00548; Sat, 11 Mar 89 09:15:39 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903111615.AA00548@defun.utah.edu>
Date: Sat, 11 Mar 89 09:15:37 MST
Subject: Re: issue CLOS-MACRO-COMPILATION, version 1
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Fri, 10 Mar 89 18:06:53 CST
> Date: Fri, 10 Mar 89 18:06:53 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
>
> > [This also seems to imply that tests for existence of the generic
> > function, lambda-list congruence, etc. must not happen until
> > load time.]
>
> No, an implementation should be permitted to check for lambda-list
> congruence between methods defined in the same file; this doesn't
> require any reference to the resident generic function definition. If
> the file doesn't include a DEFGENERIC, then the first DEFMETHOD defines
> the compile-time generic function attributes, and subsequent methods can
> be checked against that.
The description of DEFMETHOD in CLOS chapter 2 talks about calling
FBOUNDP and signalling an error if the function is not a generic
function, or if it is a generic function but the lambda list of the
method is not congruent. Clearly this shouldn't happen at
compile-time. I agree that the behavior you suggest makes more sense.
>
> > DEFINE-METHOD-COMBINATION:
> >
> > * The method combination can be used in a subsequent DEFGENERIC. If it
> > is referenced, the body of a long form of method combination must be
> > evaluable at compile-time.
>
> But if methods are not installed at compile time and generic functions
> are not callable at compile time, then I don't think there is any
> situation in which the method combination body could be executed at
> compile-time.
This is something I couldn't quite figure out from reading chapters 1
& 2. At what time does the method combination become "integrated"
into the DEFGENERIC? Does the process of expanding the DEFGENERIC
macro capture the method combination definition, in the same way that
expanding a SETF macro captures the setf method? Or does this happen
when you actually execute the DEFGENERIC macro?
-Sandra
-------
∂11-Mar-89 1220 Common-Lisp-Object-System-mailer Re: issue CLOS-MACRO-COMPILATION, version 1
Received: from ti.com by SAIL.Stanford.EDU with TCP; 11 Mar 89 12:19:38 PST
Received: by ti.com id AA10411; Sat, 11 Mar 89 14:18:09 CST
Received: from Kelvin by tilde id AA14567; Sat, 11 Mar 89 14:14:39 CST
Message-Id: <2814639239-9369595@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Sat, 11 Mar 89 14:13:59 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu
Subject: Re: issue CLOS-MACRO-COMPILATION, version 1
In-Reply-To: Msg of Sat, 11 Mar 89 09:15:37 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> The description of DEFMETHOD in CLOS chapter 2 talks about calling
> FBOUNDP and signalling an error if the function is not a generic
> function, or if it is a generic function but the lambda list of the
> method is not congruent. Clearly this shouldn't happen at
> compile-time.
Right, unless it is viewed as doing the FBOUNDP in the compile-time
environment without inheritance from the resident environment.
> > But if methods are not installed at compile time and generic functions
> > are not callable at compile time, then I don't think there is any
> > situation in which the method combination body could be executed at
> > compile-time.
>
> This is something I couldn't quite figure out from reading chapters 1
> & 2. At what time does the method combination become "integrated"
> into the DEFGENERIC? Does the process of expanding the DEFGENERIC
> macro capture the method combination definition, in the same way that
> expanding a SETF macro captures the setf method? Or does this happen
> when you actually execute the DEFGENERIC macro?
This is only in chapter 3, and not very clear there even. My
understanding of it is that the method combination body would be invoked
from COMPUTE-EFFECTIVE-METHOD, which, depending on the implementation,
could be invoked as soon as a call to ADD-METHOD, or as late as a call
to the generic function which actually needs that particular
combination. Since it operates on a list of applicable methods, it
couldn't be invoked from DEFGENERIC. The generic function object would
just have a pointer to the method combination object for future use.
∂11-Mar-89 1243 CL-Compiler-mailer issue PROCLAIM-ETC-IN-COMPILE-FILE, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Mar 89 12:43:42 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA07469; Sat, 11 Mar 89 13:41:29 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00673; Sat, 11 Mar 89 13:41:26 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903112041.AA00673@defun.utah.edu>
Date: Sat, 11 Mar 89 13:41:24 MST
Subject: issue PROCLAIM-ETC-IN-COMPILE-FILE, version 3
To: cl-compiler@sail.stanford.edu
I've done a total rewrite on this issue. There are now three
proposals, which I think cover the range of possibilities. I think
that doing nothing with this issue would be the equivalent of
approving proposal NO.
I was going to send this out to X3J13 with our other proposals on
Monday. I realize that doesn't give you folks enough time to review
this properly, so I've marked it as being a draft. We can bring a
revised version to the meeting or decide not to bring it up for a
vote, if necessary.
Issue: PROCLAIM-ETC-IN-COMPILE-FILE
References: CLtL p. 182 [package functions],
p. 156 [PROCLAIM], p. 439 [COMPILE-FILE];
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue IN-PACKAGE-FUNCTIONALITY
Issue EVAL-WHEN-NON-TOP-LEVEL
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CLARIFICATION, CHANGE, ADDITION
Edit History: 15 Sep 88, V1 by David Gray
23 Sep 88, V2 by Sandra Loosemore (summarize discussion)
11 Mar 89, V3 by Sandra Loosemore (rewrite)
Status: **DRAFT**
Problem Description:
Should the compiler treat top-level calls to PROCLAIM specially?
Page 182 of CLtL says that COMPILE-FILE needs to treat top-level calls
to the following package functions as though they were wrapped in an
(EVAL-WHEN (COMPILE LOAD EVAL) ...):
EXPORT IMPORT IN-PACKAGE MAKE-PACKAGE SHADOW
SHADOWING-IMPORT UNEXPORT UNUSE-PACKAGE USE-PACKAGE
CLtL is silent on whether top-level calls to PROCLAIM should also be
evaluated at compile-time, which presumably means they shouldn't be.
However, some implementations do evaluate PROCLAIM at compile-time.
In the model of how COMPILE-FILE works that is presented in issues
EVAL-WHEN-NON-TOP-LEVEL and DEFINING-MACROS-NON-TOP-LEVEL, the special
form EVAL-WHEN is the only thing that can cause compile-time evaluation
to occur. The compile-time side-effects of macros such as DEFMACRO
and DEFPACKAGE are explained by having them include EVAL-WHEN in their
expansions. Any functions that are treated specially, however, must
be included as special cases in the compiler.
Proposal IN-PACKAGE-FUNCTIONALITY:NEW-MACRO would remove the
requirement that the package functions be treated specially. Do we
wish to make an exception to the model for PROCLAIM?
Proposal PROCLAIM-ETC-IN-COMPILE-FILE:YES:
Require COMPILE-FILE to treat top-level calls to PROCLAIM as if they
were wrapped in an (EVAL-WHEN (COMPILE LOAD EVAL) ...).
Rationale:
Proclamations affect compilation semantics and should be made
available to the compiler.
Proposal PROCLAIM-ETC-IN-COMPILE-FILE:NO:
Clarify that calls to PROCLAIM should be treated the same as any
other function call. Users should wrap an explicit EVAL-WHEN around
top-level calls to PROCLAIM if they want them to affect compilation.
Rationale:
This makes the semantics of COMPILE-FILE more uniform and easier
to understand. In particular, if we remove the magic compile-time
behavior of the package functions, it seems silly to add another
exception for PROCLAIM.
Proposal PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO:
Add a new macro:
DEFPROCLAIM &rest decl-specs [Macro]
This macro PROCLAIMs the given <decl-specs>, which are not
evaluated. If a call to this macro appears at top-level in a file
being processed by the file compiler, the proclamations are also
made at compile-time. As with other defining macros, it is
unspecified whether or not the compile-time side-effects of a
DEFPROCLAIM persist after the file has been compiled.
Clarify that calls to PROCLAIM should be treated the same as any
other function call. Users should wrap an explicit EVAL-WHEN around
top-level calls to PROCLAIM if they want them to affect compilation,
or use the macro DEFPROCLAIM.
Rationale:
The macro makes the proclamations available to the compiler in such
a way that does not require any special exceptions to be made in
the model of how COMPILE-FILE works.
Current Practice:
The TI explorer apparently implements proposal YES, except that
(EVAL-WHEN (LOAD) (PROCLAIM '(OPTIMIZE ...))) doesn't do anything.
The Symbolics compiler has special top-level handling for PROCLAIM,
although the details are not clear.
Lucid does not evaluate calls to PROCLAIM at compile-time.
Cost to implementors:
Since implementations are already required to have a mechanism for
compile-time handling of the package functions, it would probably
only require minor adjustments to add handling for PROCLAIM.
Cost to users:
For proposal YES, users would have no way to suppress compile-time
evaluation of a top-level call to PROCLAIM. Wrapping it in an
(EVAL-WHEN (EVAL LOAD)...) wouldn't work under the model of how
EVAL-WHEN works in proposal EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL.
Under any of these proposals, some users would probably have to
make minor changes to their code.
Benefits:
Users will know what to expect when they use PROCLAIM.
Costs of Non-Adoption:
Users will not know what to expect when they use PROCLAIM.
Aesthetics:
At least two people consider requiring magic behavior for certain
top-level function calls to be "semantically bletcherous". Removing
all special cases for functions that are implicitly evaluated at
compile-time would simplify the model of how COMPILE-FILE works.
Programs look cleaner if EVAL-WHEN is only needed for unusual cases
instead of being required for the normal cases.
Discussion:
The first version of this writeup also included REQUIRE with PROCLAIM,
but we have now voted to remove REQUIRE from the language entirely.
It also specified that OPTIMIZE proclamations should only have a local
effect within the file being compiled. This was removed for
consistency with other compile-time side-effects (such as those from
DEFMACRO), where their persistence is explicitly left unspecified.
Loosemore favors proposal NO, but wouldn't oppose proposal NEW-MACRO.
-------
∂11-Mar-89 1304 CL-Compiler-mailer Issue: DEFINE-OPTIMIZER (Version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Mar 89 13:01:47 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 555145; Sat 11-Mar-89 15:58:46 EST
Date: Sat, 11 Mar 89 15:58 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: DEFINE-OPTIMIZER (Version 4)
To: cperdue@Sun.COM
cc: CL-Compiler@SAIL.Stanford.EDU
Message-ID: <890311155827.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
[A revised proposal (v4) follows at the end of my reply to Cris.]
Date: Fri, 10 Mar 89 14:35:06 PST
From: cperdue@Sun.COM (Cris Perdue)
... I support Kent's proposal, with the following suggestions:
An additional function that corresponds to MACRO-FUNCTION for ordinary
macros. I include the proposed definition for this, which follows the
definition of MACRO-FUNCTION in CLtL, p144. This provides
primitive-level access, including the ability to undefine an
optimizer.
The current definition is agnostic about whether built-in system
optimizers are implemented using DEFINE-OPTIMIZER or vice versa.
This is important for two reasons:
- System optimizations may be type dispatched, as mentioned
in earlier discussions. In such cases, the general mechanism
proposed here could effectively define optimizations on type T
and not override more specific optimizations.
- Some systems may permit multiple optimizers for the same
function. In such a case, the optimizer set up by DEFINE-OPTIMIZER
may be only one of several.
Adding your OPTIMIZER-FUNCTION would expose the implementation, by
forcing us to say whether all the optimizers were captured, or only
the ones defined by DEFINE-OPTIMIZER. The interface I chose tries
deliberately to hide this issue in order to keep us from getting
bogged down in those other issues.
Similar arguments apply to the issue of undefining optimizers.
In both cases, I think you're describing very useful features and
I encourage you to (a) extend your implementation, (b) propose those
interfaces on the next standardization cycle.
The issue for now is that this proposal is essentially unchanged since
the last time I brought it up, but last round I made the mistake of
hinting that other issues might get involved so everyone immediately
went off in a million different directions and Sandra marked the
proposal as without clear support. I think she was right, and I think
what makes this time different is that the focus is just enough
different that we can all agree that this much functionality is ok.
Add to the problem description that sometimes an "operator" is defined
as a macro purely because its performance would be inadequate if
implemented as a function.
Good idea.
Also, I believe it would be best to state that in environments where
the compiler is prohibited from treating a function as INLINE,
optimizers are deactivated. In particular, the functions
OPTIMIZE-EXPRESSION and OPTIMIZE-EXPRESSION-1 do not transform their
expression argument if given an environment in which the function must
not be treated as INLINE. (I recognize that this is a bit of
a judgment call.)
The point here is to make user-defined optimizers follow the behavior
of optimizers built-in to compilers in their response to NOTINLINE.
I agree this is a problem, but I don't want to solve it this way because,
as you say, it's a judgment call, and I don't want to jeopardize the
whole thing if someone gets nervous. I will add wording saying that the
effects of having an OPTIMIZER on a function which is also proclaimed
INLINE are ``unspecified but harmless'' (in that both optimizations and
inlining are intended to be semantics-preserving operations).
-----
Forum: Compiler
Issue: DEFINE-OPTIMIZER
References: Issue SYNTACTIC-ENVIRONMENT-ACCESS
Category: ADDITION
Edit history: 28-Sep-88, Version 1 by Pitman
10-Mar-89, Version 2 by Pitman (clarifications, new example),
10-Mar-89, Version 3 by Pitman & Loosemore
Status: Ready for release
Problem Description:
Often a general functional interface could be bypassed given explicit
knowledge of the arguments passed. This may happen when the arguments
are constant (or otherwise inferrable), an argument type is known (eg,
due to use of THE or DECLARE), or when some particular pattern of
optional, rest or keyword arguments is apparent.
Most implementations provide internally for optimization of generalized
function call interfaces to more specialized ones, but such an
optimization facility is not provided to Common Lisp users.
The absence of this facility in a portable fashion means that some
CL programs run slower than they need to in some implementations, or
else that some operators that should be implemented as functions end
up getting implemented as macros to assure needed efficiency.
Proposal (DEFINE-OPTIMIZER:NEW-FACILITY):
Introduce a facility for declaring compiler optimizations.
DEFINE-OPTIMIZER name arglist {declaration}* {form}* [Macro]
Defines a compiler optimizer for a function named NAME. The ARGLIST,
DECLARATIONS, and FORMS are treated exactly like the arglist,
declarations, and forms in a DEFMACRO. (The arglist may include
&ENVIRONMENT and &WHOLE.)
The argument NAME must name a function which has been previously
defined. The effects of defining an optimizer for a locally or
globally defined macro, a locally defined function, or a special
form are undefined.
When the optimizer is invoked, the forms are executed in the context
of bindings specified by the arglist, and two values are yielded,
RESULT and VALID-P. (If either of the first or second return value
is non-NIL, then the first return value is considered valid).
If the result is valid, it is a form which is preferrable to evaluate
instead of the indicated call.
If a call to DEFINE-OPTIMIZER appears at top-level in a file
being processed by the file compiler, it also makes the optimizer
known at compile-time (similar to the way DEFMACRO makes a macro
definition known to the compiler).
OPTIMIZE-EXPRESSION-1 form env [Function]
Similar to MACROEXPAND-1. Invokes the optimizers for the top level of
FORM, but does not iterate on the result. Returns two values:
RESULT and CHANGED-P.
Note: If an optimizer returns a result which is not valid,
OPTIMIZE-EXPRESSION-1 hides the fact by returning FORM,NIL
rather than NIL,NIL.
OPTIMIZE-EXPRESSION form env [Function]
Iterates calling OPTIMIZE-EXPRESSION-1 until the CHANGED-P result
is NIL.
An implementation must save optimizer definitions created by
DEFINE-OPTIMIZER in case OPTIMIZE-EXPRESSION is attempted, but is
not actually required to call OPTIMIZE-EXPRESSION itself. Interpreters,
for example, may choose to just call the unoptimized form.
Using FLET and MACROLET shadow not only functions and their SETF methods,
but also their optimizers. No portable facility is provided for creating
locally defined optimizers.
The effect of defining optimizations for functions on the LISP package
is not defined. (In some implementations, this would clobber or conflict
with existing advice that may be of higher quality.)
The editor is advised that a non-binding style note such as the
following would also be appropriate:
In general, it is poor style for a programmer to define optimizers for
functions that he does not maintain. This is because the correct
implementation of an optimizer for a function usually depends on an
understanding of the internals of that function. As such, a function
definition and any optimizers should be maintained as a unit so that
they can changes in either can be synchronized as appropriate with the
other.
The effect of using DEFINE-OPTIMIZER on a function declared to be
INLINE is ``unspecified but harmless'' (per new Error Terminology).
That is, since both operations (optimization and inlining) are intended
to be semantics-preserving, no functional difference should be observed.
However, in some implementations the presence of an optimizer may thwart
the ability to inline, or vice versa. Writers of portable are encouraged
to use either DEFINE-OPTIMIZER or (PROCLAIM '(INLINE ...)) but not both.
Example:
;; These examples are taken literally from the Macsyma sources,
;; modified only to change DEFOPT to DEFINE-OPTIMIZER. The comments
;; were specially written for the X3J13 audience.
;; M+ is adds a Macsyma expression to another Macsyma expression.
;; The Macsyma internal representation for the sum of X and Y is
;; ((MPLUS) X Y). A all the real work is done by SIMPLIFY, which
;; reduces the expression as needed necessary. However, SIMPLIFY
;; is very complicated, and considerable speed can be gained by
;; entering it at specific known places.
(DEFUN M+ (&REST TERMS)
(PROTECT-&REST-VARIABLE TERMS)
(SIMPLIFY `((MPLUS) ,@TERMS)))
(DEFINE-OPTIMIZER M+ (&REST TERMS)
(COND ((= (LENGTH TERMS) 2) `(ADD2* ,@TERMS))
(T `(ADDN (LIST ,@TERMS) NIL))))
;; M- negates a Macsyma expression, or substracts two Macsyma
;; expressions. Once you figure out which of the two operations is
;; to be done, the problem is similar to that of M+ above. However,
;; often the decision can be made at compile time. In this case,
;; INLINE functions would have worked ok, except that not all
;; implementations do inlining, and even those that do may fail to
;; recognize that EXP2 being NIL means that a test can be eliminated
;; or dead code can be eliminated. Using optimizers is far more
;; likely to be useful in practice.
(DEFUN M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
(M--INTERNAL-NEGATE EXP1)
(M--INTERNAL-SUBTRACT EXP1 EXP2)))
(DEFINE-OPTIMIZER M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
(IF (NOT EXP2P)
`(M--INTERNAL-NEGATE ,EXP1)
`(M--INTERNAL-SUBTRACT ,EXP1 ,EXP2)))
Rationale:
Many large portable applications expect such a facility on an
implementation-specific basis. Others would use one if available.
Even if implementations don't use the provided optimizers primitively,
user macros and code-walkers can invoke them, so the facility wouldn't
be completely useless even in those implementations.
Current Practice:
Symbolics Genera provides an optimizer facility which is more elaborate
but not fundamentally incompatible with this facility.
Many (if not most) serious implementations provide a similar facility.
For example, Lucid provides "compiler macros" which serve the same
purpose.
Cost to Implementors:
Since the implementation is not required to use this facility, the
cost of providing the proposed support is very small.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Portable code would be slower than necessary in some situations.
Benefits:
Some existing non-portable code could become portable.
Aesthetics:
Providing a separate optimizer definition from a main function definition
makes a possibility that the optimizer and main function could drift out
of synch. However, most places where this gets used in the first place
are places where speed is of paramount importance and the programmer is
willing to invest effort in maintaining things correctly and to accept the
risk of lossage if s/he fails.
This is a fairly clean and simple extension which adds significant
power to the compiler.
Discussion:
Pitman strongly supports this proposal, the design of which is modeled
directly after that which has been used in Macsyma for many years.
Information about argument type can come from two different sources:
THE and declarations (via PROCLAIM or DECLARE). The former information
is portably accessible, the latter is not. While a separate proposal
(SYNTACTIC-ENVIRONMENT-ACCESS) for allowing program access to type
declarations would be make this facility more useful, it is still
quite useful without it, as the examples from Macsyma illustrate.
Some implementations provide a way to provide more than one optimizer
for the same function. A multiple optimizer facility can be written
in terms of this simpler facility and vice versa, so the simpler of
the two facilities is proposed here.
Some people have suggested that they would like to see a pattern
matching facility integrated into this facility. The design of a
facility that would satisfy everyone would take a lot of time and
effort. At this point, there is no chance that the design of such a
facility would occur in time for acceptance into the standard.
The choice is this or nothing. Pitman thinks the language is much
better off with some form of optimization support than none.
Loosemore says:
Although I don't really think this is an essential feature to include
in the standard, I don't have any strong objection to adding it. If
people think it's a good idea to provide a standard interface for this
kind of thing, this is a good proposal for doing it -- it's fairly
simple, doesn't introduce any radically new ideas, and is general
enough to allow alternate interfaces (such as the pattern matcher) to
be layered on top of it.
∂11-Mar-89 1321 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
Received: from ti.com by SAIL.Stanford.EDU with TCP; 11 Mar 89 13:20:53 PST
Received: by ti.com id AA10598; Sat, 11 Mar 89 15:19:03 CST
Received: from Kelvin by tilde id AA15498; Sat, 11 Mar 89 15:09:15 CST
Message-Id: <2814642505-9565798@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Sat, 11 Mar 89 15:08:25 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: cl-compiler@sail.stanford.edu,
"David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>,
"Kim A. Barrett" <IIM%ECLA@ECLC.USC.EDU>
Subject: Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
In-Reply-To: Msg of Sat, 11 Mar 89 09:03:42 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> This is too vague. What does "scope of that information" mean? Dynamic
> scope? Lexical scope? You need to say what the *extent* is, not the
> scope.
I agree the wording could use improvement. The idea is that the extent
of the information is the time during which the processor is processing
the code within that scope.
> An example may clarify my confusion. :-) Suppose I'm using
> LOCAL-TYPE-DECLARE as implemented in the writeup (but with
> COPY-ENVIRONMENT added to it, of course), and then I say something
> like:
>
> (defun f (x)
> (local-type-declare ((x fixnum))
> #'(lambda (y)
> (local-type-declare ((y fixnum))
> (+ (typed var x) y)))
> ))
>
> Is this legitimate? Let's assume that the interpreter doesn't do a
> code walk. The closure returned when you call F has indefinite
> extent, yet it contains a reference to the environment established by
> the lexically enclosing LOCAL-TYPE-DECLARE. So if this is legal,
> the environment has to have indefinite extent too.
This wouldn't be any problem when compiled, but you are right that an
interpreter that expands macros during execution would need to use a
macro expansion environment with indefinite extent. I hadn't thought of
that difference before. Of course, though, such an implementation would
have to support indefinite-extent macro environments internally in order
to correctly implement closures regardless of the
MACRO-ENVIRONMENT-EXTENT issue, so there shouldn't be any hardship for
it to permit more explicit use of saved environments. In any case, I
have no objection to saying that local macro definitions have indefinite
extent, it's just the other things that environments might be used for
that worries me.
> Rather than trying to add all these ill-defined qualifications and
> restrictions, if we absolutely cannot agree to give environments
> indefinite extent (or to provide a copier to give them indefinite
> extent), I would much rather see a simple statement that you can't
> assume more than dynamic extent.
Maybe a simpler way to look at it is that you can't expect to be able to
extract from an environment object information that would not be present
(although possibly shadowed) in the environment that would be given to a
macro expander in the current lexical context. Thus, your example would
be permitted because the saved environment used by the local macro
TYPED-VAR is a lexical ancestor of the environment that the expander is
given directly. You aren't trying to access a definition that doesn't
exist anymore, just something that might be shadowed in the current
environment.
Similarly, a saved environment could be used to access class definitions
later during COMPILE-FILE, because all environments after that time will
include the same class definitions.
Does that make the concept any clearer?
> > Within COMPILE-FILE, class definitions resulting from a top-level
> > DEFCLASS can not be accessed after processing of the file is complete.
>
> As far as I've been able to tell, there is nothing in CLOS chapters 1
> & 2 that says that DEFCLASS *must* store class definitions in any
> particular way that involves environment objects.
The problem is with FIND-CLASS, which is documented on page 2-48 to
accept an environment argument:
"The optional environment argument is the same as the &ENVIRONMENT
argument to macro expansion functions. It is typically used to
distinguish between compile-time and run-time environments."
Perhaps this feature ought to be moved to chapter 3, since it doesn't
help much to have this included in the standard without the supporting
specifications that makes it meaningful.
∂11-Mar-89 1502 CL-Compiler-mailer Re: issue CLOS-MACRO-COMPILATION, version 1
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Mar 89 15:02:28 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 555181; Sat 11-Mar-89 17:58:31 EST
Date: Sat, 11 Mar 89 17:58 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue CLOS-MACRO-COMPILATION, version 1
To: David N Gray <Gray@DSG.csc.ti.com>
cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>, cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
In-Reply-To: <2814566813-5018117@Kelvin>
Message-ID: <19890311225826.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 10 Mar 89 18:06:53 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> Proposal CLOS-MACRO-COMPILATION:MINIMAL:
...
> DEFMETHOD:
>
> * The method is not callable at compile-time. If there is a generic
> function with the same name at compile-time, compiling a DEFMETHOD
> will not add the method to that generic function.
>
> [This also seems to imply that tests for existence of the generic
> function, lambda-list congruence, etc. must not happen until
> load time.]
No, an implementation should be permitted to check for lambda-list
congruence between methods defined in the same file; this doesn't
require any reference to the resident generic function definition. If
the file doesn't include a DEFGENERIC, then the first DEFMETHOD defines
the compile-time generic function attributes, and subsequent methods can
be checked against that.
Agreed. I would phrase it differently: all the DEFGENERICs and DEFMETHODS
for a given generic function name in a given compilation unit can be checked
against each other for lambda-list congruence.
> DEFINE-METHOD-COMBINATION:
>
> * The method combination can be used in a subsequent DEFGENERIC. If it
> is referenced, the body of a long form of method combination must be
> evaluable at compile-time.
But if methods are not installed at compile time and generic functions
are not callable at compile time, then I don't think there is any
situation in which the method combination body could be executed at
compile-time.
Some implementations compose and compile effective methods at compile
time, which of course requires evaluating the body of the
define-method-combination at compile time.
I haven't read Sandra's proposal yet.
∂11-Mar-89 1531 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Mar 89 15:31:22 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA10960; Sat, 11 Mar 89 16:29:10 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00784; Sat, 11 Mar 89 16:29:08 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903112329.AA00784@defun.utah.edu>
Date: Sat, 11 Mar 89 16:29:06 MST
Subject: Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: sandra%defun@cs.utah.edu (Sandra J Loosemore),
cl-compiler@sail.stanford.edu,
"David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>,
"Kim A. Barrett" <IIM%ECLA@ECLC.USC.EDU>
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Sat, 11 Mar 89 15:08:25 CST
Hmmm. It sounds to me like you want the environment to have an extent
similar to the extent of the special bindings made by COMPILER-LET.
How about some wording like:
The extent of the environment objects passed to MACROEXPAND or
MACROEXPAND-1 by COMPILE-FILE, COMPILE, and EVAL is the dynamic extent
during which the macro and its expansion are processed. In
particular, the extent includes the expansion of any other macro calls
appearing lexically within the form returned from MACROEXPAND or
MACROEXPAND-1.
I think this would fit in with issue SYNTACTIC-ENVIRONMENT-ACCESS, but
I'm still confused about why you would still need COPY-ENVIRONMENT.
One other thing that's still not really clear to me is why you think
this is better than just saying they have (or can be copied to have)
indefinite extent. It would make the typed-variable example work but
not be of much use for macro-caching. Can you provide a more specific
rationale than just saying that it gives implementors more flexibility?
-Sandra
-------
∂11-Mar-89 1621 CL-Compiler-mailer Issue CONSTANT-COMPILABLE-TYPES, version 7
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 11 Mar 89 16:21:33 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01042g; Sat, 11 Mar 89 16:14:32 PST
Received: by challenger id AA05885g; Sat, 11 Mar 89 16:09:56 PST
Date: Sat, 11 Mar 89 16:09:56 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903120009.AA05885@challenger>
To: cl-compiler@sail.stanford.edu
Subject: Issue CONSTANT-COMPILABLE-TYPES, version 7
I guess I pretty strongly object to leaving functions out of the list
of constants that can appear in compiled code. The part that's
disturbing is that such non-Lispy things like arrays, hashtables, and
pathnames get better treatment than functions, the most Lispy part of
Common Lisp. I wonder how many implementations will be forced to come
within an inch of the required functionality to implement a first-rate
CLOS?
The specification of the subset of functions that are acceptable as
compiled constants cannot be tested for within Common Lisp itself.
I suggest we ask implementors (Lucid included) to bite the bullet and
handle this case correctly. Won't our grandchildren appreciate us
treating Common Lisp like Lisp and not like PASCAL?
Also, as will be seen in a subsequent message, there might be other
compiler issues that can be treated my esthetically were this issue
fixed up.
-rpg-
∂11-Mar-89 1643 CL-Compiler-mailer Issue CLOS-MACRO-COMPILATION, version 1
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 11 Mar 89 16:43:21 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01057g; Sat, 11 Mar 89 16:36:21 PST
Received: by challenger id AA05917g; Sat, 11 Mar 89 16:31:46 PST
Date: Sat, 11 Mar 89 16:31:46 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903120031.AA05917@challenger>
To: cl-compiler@sail.stanford.edu
Subject: Issue CLOS-MACRO-COMPILATION, version 1
Sandra writes:
``The description of DEFMETHOD in CLOS chapter 2 talks about calling
FBOUNDP and signalling an error if the function is not a generic
function, or if it is a generic function but the lambda list of the
method is not congruent. Clearly this shouldn't happen at
compile-time. I agree that the behavior you suggest makes more sense.
''
To be slightly pissant about it, Chapter 2 doesn't say this exactly.
It says that if FBOUNDP of the function specifier is NIL, certain
actions take place, and if other conditions hold, errors are
signalled. The wording is chosen so as to not imply that FBOUNDP is
called at any particular time, nor is it necessary for FBOUNDP to ever
be called. Just as in the current ADJUST-ARRAY issue, the operative
phrase is about whether the result of a call would be something
particular.
Chapter 1 and 2 are written in such a way that the semantics of a
correct, well-formed program are specified. The model that Linda and I
(the two writers) had in mind was that of well-formed programs being
either loaded into a fresh Lisp or of being compiled in a fresh Lisp
and then loaded into a fresh Lisp. We tried to specify the minimally
required semantics of such well-formed programs.
The question I have about the process going on with respect to the
CLOS-MACRO-COMPILATION issue is whether the fine-grained behavior of
CLOS under various compilation/evaluation situations is being
over-specified.
At this stage of the game I worry that we might go a little too far in
one direction in specification when we are actually engaged in design
work. This isn't intended to be a criticism of any committees, but I
would feel a lot more comfortable with a conservative specification
that defined well-formed programs being loaded or compiled in fresh
Common Lisps with a pretty simple eval-when model that is easier to
specify and which makes it easy for all but the hairiest
compilation-environment-frobbing programs to be written. What tips me
off to this is the heroic effort I see Sandra and the other compiler
committee members making to understand the ultimately hairy
situations.
I know this makes the specification of Common Lisp more like
specifications of Ada or PASCAL, but at least we have a better chance
of not blowing it.
-rpg-
∂11-Mar-89 1658 Common-Lisp-Object-System-mailer Issue: LOAD-OBJECTS (Version 3)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 11 Mar 89 16:58:32 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01066g; Sat, 11 Mar 89 16:51:27 PST
Received: by challenger id AA05936g; Sat, 11 Mar 89 16:46:51 PST
Date: Sat, 11 Mar 89 16:46:51 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903120046.AA05936@challenger>
To: CL-Cleanup@sail.stanford.edu, CL-Compiler@sail.stanford.edu,
Common-Lisp-Object-System@sail.stanford.edu
Subject: Issue: LOAD-OBJECTS (Version 3)
I was a little surprised to see that this proposal talks about load
forms instead of load functions (which goes to show how much I've been
paying attention). After some thought and consultation with Moon, I
realized that part of it was that compiled functions could not be
compiled constants. If we were to allow such constants, I would propose
we consider the alternative of load functions.
The model would be that when objects are being either prepared for
dumping or are being dumped, at certain points the generic function
MAKE-LOAD-FUNCTION would be invoked on objects that needed to be
re-created later. It would return either one or two functions. The
first is a function of 0 arguments that does the initial creation, and
the second is (if present) a function of 1 argument, which is the
initializer. If present it is applied to the created instance. This
simplifies the naming problem in the current proposal, which, while
clever, is a little unpalatable. In particular, it introduces yet
another way to think about variables.
I think people will find the macro approach (the current approach)
baroque, partly because the approach is best understood by thinking of
an input phase to a compiler or some such program, rather than by
thinking about an output phase when everything has already been supposedly
created. For example, when I read the current proposal, I imagined it
in the FASDUMP phase.
One drawback of my proposal is that the function approach is a little
more verbose in some cases. I also think it is subject to more
circularity errors by novices than the macro approach. On the other
hand, the functional approach makes one think about the issues a
little harder when writing the code, which is possibly a good thing.
Here are the examples in the macro proposal:
;; Example 1
(defclass my-class ()
((a :initarg :a :reader my-a)
(b :initarg :b :reader my-b)
(c :accessor my-c)))
(defmethod shared-initialize ((self my-class) ignore &rest ignore)
(unless (slot-boundp self 'c)
(setf (my-c self) (some-computation (my-a self) (my-b self)))))
(defmethod make-load-function ((self my-class))
(let ((name (class-name (class-of self)))
(a (my-a self))
(b (my-b self)))
#'(lambda () (make-instance name :a a :b b))))
Here the computations of NAME, A, and B must be outside the function
#'(lambda ...) so that they get evaluated in the right environment to
avoid a circular (self-referential) structure. For this to work, the
faslout of #'(lambda ...) must also notice any constants or such
things that need similar treatment, which will get NAME, A, and B, if
needed.
;; Example 2
(defclass my-frob ()
((name :initarg :name :reader my-name)))
(defmethod make-load-function ((self my-frob))
(let ((name (my-name self)))
#'(lambda () (find-my-frob name :if-does-not-exist :create))))
Maybe NAME is not something to worry about, but SELF cannot appear in
the #'(lambda ...).
;; Example 3 (expanded to do a hairy thing that cannot be easily done
;; in the macro approach).
(defclass tree-with-parent () ((parent :accessor tree-parent)
(curious-facts :accessor tree-foma)
(children :initarg :children)))
(defmethod make-load-function ((x tree-with-parent))
(let ((class (class-of x))
(children (slot-value x 'children))
(random-info-at-dump-time (compute-random-info x))
(more-random-info-at-creation-time ())
(parent (slot-value x 'parent)))
(flet ((initialize (x)
(setf (tree-foma x)
(combine-info random-info-at-dump-time
random-info-at-creation-time))
(setf (tree-parent x) parent)))
(values
;; creation
#`(lambda ()
(setq more-random-info-at-creation-time
(compute-more-random-info))
(make-instance class :children children))
;; initialization
#'initialize))))
One can imagine the shared lexical environment of the creator and initializer
being a high-bandwidth channel for information, such as the important
information passed in the above example.
Finally, I wouldn't use the name MAKE-LOAD-FUNCTION-USING-SLOTS,
because the structure of the name ...-USING-SLOTS is like
...-USING-CLASS, which is named that way to inform the programmer that
he can discriminate on the metaclass. Maybe,
MAKE-LOAD-FUNCTION-PRESERVING-SLOTS?
-rpg-
∂11-Mar-89 1718 CL-Compiler-mailer Re: Issue CONSTANT-COMPILABLE-TYPES, version 7
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 11 Mar 89 17:18:10 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
id AA19653; Sat, 11 Mar 89 17:18:56 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
id AA20560; Sat, 11 Mar 89 17:15:13 PST
Received: by clam.sun.com (4.0/SMI-4.0)
id AA18680; Sat, 11 Mar 89 17:18:44 PST
Date: Sat, 11 Mar 89 17:18:44 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903120118.AA18680@clam.sun.com>
To: cl-compiler@sail.stanford.edu, rpg@lucid.com
Subject: Re: Issue CONSTANT-COMPILABLE-TYPES, version 7
Dick,
> I guess I pretty strongly object to leaving functions out of the list
> of constants that can appear in compiled code. The part that's
> disturbing is that such non-Lispy things like arrays, hashtables, and
> pathnames get better treatment than functions, the most Lispy part of
> Common Lisp. I wonder how many implementations will be forced to come
> within an inch of the required functionality to implement a first-rate
> CLOS?
Thanks for the note. I feel a good deal the way you do about the
importance of functions.
> The specification of the subset of functions that are acceptable as
> compiled constants cannot be tested for within Common Lisp itself.
Sigh. Did we remove compiled-function-p from the language? My
thought was that functions not closing over any variables and
for which this test would return NIL would have to be accepted
as compiled constants.
> I suggest we ask implementors (Lucid included) to bite the bullet and
> handle this case correctly. Won't our grandchildren appreciate us
> treating Common Lisp like Lisp and not like PASCAL?
There are technical issues regarding closures, and since you are
interested, I solicit your opinion:
There is of course a set of lexical variables and their state
associated with each closure. Most objects resulting from
file-compilation and loading may be made immutable (as specified
in the proposal). This would seem inappropriate for the closed-over
variables and the objects referred to by those variables.
Is this your view also?
There is also an issue concerning how carefully to preserve the
identities of variables closed over by more than one compiled and
reloaded closure. Finally (I hope this is all) there are issues
concerning how carefully to preserve the identities ("EQ-ness") of
objects referred to by closed-over variables. Uninterned symbols
presented similar issues, and careful preservation of identity turned
out to be desired there.
Basically I have been reluctant to take on the picky technical
issues here, but I hope someone else will have more energy on this
than I have. A cleanup proposal that would amend/augment
CONSTANT-COMPILABLE-TYPES:SPECIFY would be welcome.
-Cris
∂11-Mar-89 1745 Common-Lisp-Object-System-mailer Re: Issue: LOAD-OBJECTS (Version 3)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Mar 89 17:45:12 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA13023; Sat, 11 Mar 89 18:43:00 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00878; Sat, 11 Mar 89 18:42:57 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903120142.AA00878@defun.utah.edu>
Date: Sat, 11 Mar 89 18:42:56 MST
Subject: Re: Issue: LOAD-OBJECTS (Version 3)
To: Richard P. Gabriel <rpg@lucid.com>
Cc: CL-Cleanup@sail.stanford.edu, CL-Compiler@sail.stanford.edu,
Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: Richard P. Gabriel <rpg@lucid.com>, Sat, 11 Mar 89 16:46:51 PST
I haven't been paying too much attention to this issue either -- I've
been trusting Moon to do the right thing on the assumption that he
knew more about it than I did. I think his latest proposal does look
reasonable. However, if there is disagreement about it, I might as
well suggest yet another alternative:
Have two generic functions, not one. The first would get called by
compile-file and it would return a list of components (or whatever)
that are required to reconstruct the object. The compiler would dump
this list of objects in its usual way. The loader would apply the
second generic function to this list to reconstruct the object. It
avoids the nasty syntax you object to, doesn't require functions to be
dumpable, doesn't require any special support for circular constants,
and ought to be real easy to add to the compiler/loader. (You could
essentially convert the constant into a LOAD-TIME-VALUE expression.)
-Sandra
-------
∂11-Mar-89 1806 CL-Compiler-mailer Re: Issue CONSTANT-COMPILABLE-TYPES, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Mar 89 18:05:57 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA13405; Sat, 11 Mar 89 19:03:50 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA00900; Sat, 11 Mar 89 19:03:48 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903120203.AA00900@defun.utah.edu>
Date: Sat, 11 Mar 89 19:03:47 MST
Subject: Re: Issue CONSTANT-COMPILABLE-TYPES, version 7
To: cperdue@Sun.COM (Cris Perdue)
Cc: cl-compiler@sail.stanford.edu, rpg@lucid.com
In-Reply-To: cperdue@Sun.COM (Cris Perdue), Sat, 11 Mar 89 17:18:44 PST
The problem with not having a predicate to test functions that meet
the requirements is that there's no predicate for testing whether a
function is closed over any variables. See CLtL p. 89.
A further technical problem with dumping functions is that for
Lisp-callable functions that are written in microcode, machine
language, C, or whatever, it's hard to define how they should be
dumped. This applies not only to functions that the user loads with a
foreign-function interface, but to built-in functions provided as part
of the Lisp kernel. For example, suppose the kernel provides some
Lisp-callable C functions to interface to the file system, math
library, or whatever. These might be represented just as a stub that
jumps off to the address that the C linker/loader just happened to
relocate the C function at (which may differ from one invocation of
the Lisp image to the next). There's no way to determine the size of
a C function from within C, and even if you did you may not be able to
dump and reload it because maybe the C compiler didn't generate
relocatable code.
I suppose one alternative would be to say that such functions are not
FUNCTIONP but to extend APPLY, FUNCALL, etc. to accept them. Is it
legal for functions defined in the standard not to be FUNCTIONP?
-Sandra
-------
∂12-Mar-89 1002 CL-Compiler-mailer issue SYNTACTIC-ENVIRONMENT-ACCESS, version 4
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Mar 89 10:02:16 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA25589; Sun, 12 Mar 89 11:00:06 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA01408; Sun, 12 Mar 89 11:00:02 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903121800.AA01408@defun.utah.edu>
Date: Sun, 12 Mar 89 10:59:59 MST
Subject: issue SYNTACTIC-ENVIRONMENT-ACCESS, version 4
To: cl-compiler@sail.stanford.edu
I've done a rather substantial re-organization on this issue. There
are now three proposals, SMALL, MEDIUM, and LARGE. I did this because
I personally didn't feel comfortable with standardizing more than the
material in proposal SMALL at this point, and maybe others will also
be more inclined to vote for a minimal proposal than a larger one that
includes material of less obvious usefulness.
I've made the change to AUGMENT-ENVIRONMENT (adding a :DECLARE argument)
that I suggested in a previous message.
I've also removed the RECORD-ENVIRONMENT-CLEANUP function. I couldn't
think of any good examples of how or why one would want to use this,
that couldn't also be achieved by putting an explicit UNWIND-PROTECT
in the body of the WITH-REMOTE-ENVIRONMENT.
Forum: Compiler
Issue: SYNTACTIC-ENVIRONMENT-ACCESS
References: CLtL Chapter 8: Macros,
Issue MACRO-FUNCTION-ENVIRONMENT,
Issue GET-SETF-METHOD-ENVIRONMENT,
Issue COMPILE-FILE-ENVIRONMENT
Related Issues: Issue FUNCTION-NAME,
Issue PROCLAIM-LEXICAL
Issue MACRO-ENVIRONMENT-EXTENT
Category: ADDITION
Edit history: Version 1, 2-Oct-88, Eric Benson
Version 2, 17-Feb-89, Kim A. Barrett
Version 3, 9-Mar-89, Kim A. Barrett (respond to comments)
Version 4, 12-Mar-89, Sandra Loosemore (more revisions)
Status: **DRAFT**
Problem description:
When macro forms are expanded, the expansion function is called with
two arguments: the form to be expanded, and the environment in which
the form was found. The environment argument is of limited utility.
The only use sanctioned currently is as an argument to MACROEXPAND or
MACROEXPAND-1 or passed directly as an argument to another macro
expansion function. Recent cleanup issues propose to allow it as an
argument to MACRO-FUNCTION and to GET-SETF-METHOD.
It is very difficult to write a code walker that can correctly handle
local macro and function definitions, due to insufficient access to
the information contained in environments and the inability to
augment environments with local definitions.
Some people believe that the CLOS meta-object protocol will require the
ability to distinguish between remote environments used for compiling
to a file, from local environments used for processing by EVAL or
COMPILE. (However, there is no requirement in chapters 1 & 2 of the
CLOS spec that things be done this way.)
There are three proposals; SMALL, MEDIUM, and LARGE.
Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:SMALL):
The following functions provide information about syntactic
environment objects. In all of these functions the argument named ENV
is an environment of the sort received by the &ENVIRONMENT argument to
a macro or as the environment argument for EVALHOOK. Optional "env"
arguments default to NIL, which respresents the local null lexical
environment (containing only global definitions and proclamations
that are present in the runtime environment). All of these functions
should signal an error of type TYPE-ERROR if the value of an
environment argument is not a syntactic environment.
VARIABLE-KIND variable &optional env [Function]
VARIABLE is a symbol. This function returns one of the following
symbols, depending on the type of definition or binding which is
apparent in ENV.
NIL There is no apparent definition or binding for variable.
:SPECIAL VARIABLE refers to a special variable, either declared
or proclaimed.
:LEXICAL VARIABLE refers to a lexical variable.
:SYMBOL-MACRO VARIABLE refers to a SYMBOL-MACROLET binding.
:CONSTANT VARIABLE refers to a named constant, defined by
DEFCONSTANT.
[Note: If issue PROCLAIM-LEXICAL passes, then the :LEXICAL result
will also refer to variables proclaimed lexical.]
Example:
(DEFMACRO KIND-OF-VARIABLE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-KIND VAR ENV))
(DEFVAR A)
(DEFUN TEST ()
(LET (B)
(LET (C)
(DECLARE (SPECIAL C))
(SYMBOL-MACROLET ((D ANYTHING))
(LIST (KIND-OF-VARIABLE A)
(KIND-OF-VARIABLE B)
(KIND-OF-VARIABLE C)
(KIND-OF-VARIABLE D)
(KIND-OF-VARIABLE E))))))
(TEST) -> (:SPECIAL :LEXICAL :SPECIAL :SYMBOL-MACRO NIL)
FUNCTION-KIND function &optional env [Function]
FUNCTION is a function name. This function returns two values,
depending on the type of function definition or function binding
which is apparent for FUNCTION in ENV.
NIL There is no apparent definition for FUNCTION.
:FUNCTION FUNCTION refers to a function.
:MACRO FUNCTION refers to a macro.
:SPECIAL-FORM FUNCTION refers to a special form.
The second value specifies whether the definition is local or
global. If local, the second value is true, and it is false when
the definition is global.
Some function names may refer to both a global macro and a global
special form. In such a case, the macro takes precedence, and
:MACRO is returned as the first value.
[Note: The use of "function name" rather than "symbol" as the
description of the function argument is intended to be compatible
with the various proposals to extend the syntax of function
specifiers. If no such change actually occurs then this would only
refer to symbols.]
Example:
(DEFMACRO KIND-OF-FUNCTION (FUNCTION-NAME &ENVIRONMENT ENV)
`',(FUNCTION-KIND FUNCTION-NAME ENV))
(DEFUN A ())
(DEFMACRO B ())
(DEFUN TEST ()
(FLET ((C ()))
(MACROLET ((D ()))
(MULTIPLE-VALUE-CALL #'LIST
(KIND-OF-FUNCTION A)
(KIND-OF-FUNCTION B)
(KIND-OF-FUNCTION QUOTE)
(KIND-OF-FUNCTION C)
(KIND-OF-FUNCTION D)
(KIND-OF-FUNCTION E)))))
(TEST) -> (:FUNCTION NIL
:MACRO NIL
:SPECIAL-FORM NIL
:FUNCTION T
:MACRO T
NIL NIL)
VARIABLE-TYPE variable &optional env [Function]
VARIABLE is a symbol. This function returns the type specifier
associated with the variable named by the symbol in the environment.
If no explicit association exists, either by PROCLAIM or DECLARE,
then the result is the type specifier T.
The result of this function may not include all the apparent TYPE
declarations for VARIABLE. In particular, an implementation is free
to ignore TYPE declarations, only returning TYPE information which
was added to ENV by a call to AUGMENT-ENVIRONMENT.
Example:
This example assumes that the implementation records type
information in the environment, rather than ignoring it.
(DEFMACRO VARTYPE (VAR &ENVIRONMENT ENV)
`',(VARIABLE-TYPE VAR ENV))
(DEFVAR A 1)
(PROCLAIM '(FIXNUM A))
(DEFUN TEST ()
(LET ((B (AREF "X" 0))
(C 3))
(DECLARE (STRING-CHAR B))
(LIST (VARTYPE A) (VARTYPE B) (VARTYPE C))))
(TEST) -> (FIXNUM STRING-CHAR NIL)
FUNCTION-FTYPE function &optional env [Function]
FUNCTION is a function name. This function returns the functional
type specifier associated with the function in the environment, or
the symbol FUNCTION if there is no functional type declaration or
proclamation associated with the function.
The result of this function may not include all the apparent FTYPE
declarations for FUNCTION. In particular, an implementation is free
to ignore FTYPE declarations, only returning FTYPE information which
was added to ENV by a call to AUGMENT-ENVIRONMENT.
Example:
This example assumes that the implementation records ftype
information in the environment, rather than ignoring it.
(DEFMACRO FUNTYPE (FUN &ENVIRONMENT ENV)
`',(FUNCTION-FTYPE FUN ENV))
(DEFUN A-FUNCTION (X)
(+ X 3))
(PROCLAIM '(FTYPE (FUNCTION (FIXNUM) FIXNUM) A-FUNCTION))
(DEFUN TEST ()
(FLET ((ANOTHER-FUNCTION (X)
(+ X 2)))
(DECLARE (FTYPE (FUNCTION (INTEGER) INTEGER) ANOTHER-FUNCTION))
(LIST (FUNTYPE A-FUNCTION) (FUNTYPE ANOTHER-FUNCTION))))
(TEST) -> ((FUNCTION (FIXNUM) FIXNUM) (FUNCTION (INTEGER) INTEGER))
AUGMENT-ENVIRONMENT env &KEY variable
symbol-macro
function
macro
declare [Function]
This function returns a copy of ENV, augmented with the information
provided by the keyword arguments. The arguments are supplied as
follows:
:VARIABLE A list of symbols which shall be visible as bound
variables in the new environment. Whether each
binding is to be interpreted as special or lexical
depends on SPECIAL declarations recorded in the
environment or provided in the :DECLARE argument list.
:SYMBOL-MACRO A list of symbol macro definitions, in the same format
as the CADR of a SYMBOL-MACROLET special form. The
new environment will have local symbol-macro bindings
of each symbol to the corresponding expansion, so that
MACROEXPAND will be able to expand them properly.
:FUNCTION A list of function names which shall be visible as local
function bindings in the new environment.
:MACRO A list of local macro definitions, in the same format
as the CADR of a MACROLET special form. The new
environment will have local macro bindings of each
name to the corresponding expander function, which
will be returned by MACRO-FUNCTION and used by
MACROEXPAND.
:DECLARE A list of decl-specs. The new environment will
contain information about SPECIAL, TYPE, and FTYPE
declarations appearing within the list.
An error is signalled if any of the symbols naming macros in the
:SYMBOL-MACRO alist are also included in the :VARIABLE list.
An error is signalled if any of the names specified as keys in the
:MACRO alist are also included in the :FUNCTION list. The consequences
of destructively modifying the list structure of any of the arguments
to this function are undefined.
The extent of the returned environment is the same as the extent of
the argument.
While an environment argument from EVALHOOK may be used as the
environment argument for this function, the reverse is not true. If
an attempt is made to use the result of AUGMENT-ENVIRONMENT as
the environment argument for EVALHOOK, the consequences are undefined.
The environment returned by AUGMENT-ENVIRONMENT may only be used for
syntactic analysis, ie. the functions specified by this proposal and
functions such as MACROEXPAND.
[If PROCLAIM-LEXICAL is adopted, LEXICAL declarations would also
be recognized.]
Rationale:
This proposal defines a minimal set of accessors and a constructor
for environments.
The symbol-macro and macrolet definitions and declarations passed
to AUGMENT-ENVIRONMENT are in the same form as those which would
normally be encountered by a code-walker. This makes it easier to
use. In particular, there is no need for users to write their own
code to destructure macro arguments.
Making TYPE and FTYPE information optional continues to allow
implementations the freedom to simply ignore all such declarations.
Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:MEDIUM):
This is the same as proposal SMALL, but also includes:
There are two kinds of environments, local and remote. Local
environments are created by EVAL and COMPILE, and are used in
situations where the information in the environment pertains
to the immediate running Lisp environment. Remote environments
are used by processors such as COMPILE-FILE to model what the
Lisp environment will look like when the code being processed
is actually loaded.
If AUGMENT-ENVIRONMENT receives a remote environment as an argument,
then the new environment returned by this function will also be
remote, and the two will refer to the same model of the remote
environment.
ENVIRONMENT-REMOTE-P env [Function]
Returns true if ENV is a remote environment, false otherwise.
WITH-REMOTE-ENVIRONMENT var &body body [Macro]
Evaluates the BODY forms with VAR bound to a newly created remote
environment. The extent of the environment is the dynamic extent of
the WITH-REMOTE-ENVIRONMENT form.
This is the only specified mechanism by which a new remote
environment may be created.
Rationale:
The notion of local and remote environments may be useful for
developing the CLOS meta-object protocol. At some future time,
we may wish to tighten the specification of how compile-time
definitions of defining macros such as DEFMACRO or DEFCLASS are
achieved, by saying that the compile-time definitions must be made
only in the remote environment.
Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:LARGE):
This is the same as proposal MEDIUM, but also includes:
ENVIRONMENT-PROPERTY env name property &optional default
This function and its SETF method allow the association of arbitrary
'global' properties with names within an environment. An
environment can be thought of as having a local property list
associated with any name, and this function provides access to that
property list.
A remote environment may be thought of as an extension of the local
environment. Thus, when this function is applied to a remote
environment and the property is not found, the global local environment
is then searched.
The association between names and property lists uses EQUAL to match
names. The search of the property list uses EQ to match properties.
If the property is not found, DEFAULT is returned.
Using SETF of ENVIRONMENT-PROPERTY affects all environments which
refer to the same environment model. In particular, if ENV is a
local environment then all local environments are affected, while if
ENV is a remote environment, then all environments refering to the
same remote environment model as the argument are affected.
[Note: The local property list of a name is not necessarily the
symbol-plist of the name, though that is a possible implementation
for names which are symbols.
Note: The use of EQUAL as the matching function for names is to
allow for proposed extensions to function names. If no such
extension occurs, then EQ could be used instead.]
Rationale:
This would provide a mechanism for making and accessing global
definitions in the remote environment.
Cost to Implementors:
Most implementations already record some of this information in some
form. Providing these functions should not be too difficult, but it
is a more than trivial amount of work.
Cost to Users:
This change is upward compatible with user code.
Current practice:
No implementation provides all of this interface currently. Portable
Common Loops defines a subset of this functionality for its code
walker and implements it on a number of diffent versions of Common
Lisp. IIM uses the functionality provided by ENVIRONMENT-REMOTE-P
and ENVIRONMENT-PROPERTY (under other names) to implement the
association between names and remote metaobjects (macro and type
definitions, CLOS remote metaobjects, &etc).
Discussion:
The first version of this proposal expressly did not deal with the
objects which are used as environments by EVALHOOK. This version is
extended to support them in the belief that such environments share a
lot of functionality with the syntactic environments needed by a
compiler. While the two types of environments may have very
different implementations, there are many operations which are
reasonable to perform on either type, including all of the accessor
functions described by this proposal.
AUGMENT-ENVIRONMENT currently requires signaling an error when
symbol-macro names match variable names in the same call. This could
be reduced to "should signal". By requiring the error signaling, this
proposal is compatable with Proposal SYMBOL-MACROLET-DECLARE:ALLOW,
which says
"... signals an error if a SPECIAL declaration names one of the symbols
being defined as a symbol-macrolet."
Maintaining compatability with the SYMBOL-MACROLET-DECLARE proposal
allows fairly trivial implementations of the SYMBOL-MACROLET
special-form in terms of the AUGMENT-ENVIRONMENT function.
An possible alternative syntax for WITH-REMOTE-ENVIRONMENT might be
WITH-REMOTE-ENVIRONMENT (var &key) &body body
Can anyone suggest candidates for keyword options? We could do this
even if we can't think of any immediately, leaving room for
implementation-specific extensions. One candidate option that some
implementations might want would be to specify a target machine for
the compilation.
Kim Barrett originally suggested that WITH-COMPILATION-UNIT should
provide the mechanism for creating new remote environments. However,
it has been suggested that WITH-COMPILATION-UNIT is intended to serve
a somewhat different purpose.
Sandra Loosemore says:
I support proposal SMALL but would vote against both of the larger
proposals. It's true that they provide functionality which *might* be
useful to implement CLOS, but there is nothing now in the standard
that *requires* this functionality to be added. In fact, the version
of issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS that was accepted at
the January meeting explicitly leaves unspecified the mechanism by
which defining macros make definitions available to the compiler. We
have very little practical experience with using environment objects
for this purpose and I think it would be premature to try to
standardize it at this point. In particular, since the meta-object
protocol is still undergoing what appear to be substantial changes,
let's wait until it settles down and then see what kind of compiler
hooks it needs, instead of possibly standardizing the wrong thing.
-------
∂12-Mar-89 1022 CL-Compiler-mailer Issue CONSTANT-COMPILABLE-TYPES, version 7
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 12 Mar 89 10:22:27 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01313g; Sun, 12 Mar 89 10:15:26 PST
Received: by challenger id AA06612g; Sun, 12 Mar 89 10:10:49 PST
Date: Sun, 12 Mar 89 10:10:49 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903121810.AA06612@challenger>
To: cperdue@Sun.COM
Cc: cl-compiler@sail.stanford.edu
In-Reply-To: Cris Perdue's message of Sat, 11 Mar 89 17:18:44 PST <8903120118.AA18680@clam.sun.com>
Subject: Issue CONSTANT-COMPILABLE-TYPES, version 7
The subset of functions disallowed are all compiled functions and
all interpreted functions with non-null lexical environments. There is
no predicate for this.
My thought is that, as closely as possible, the fact is irrelevant
that a compiler or dumper intervened between the production of the
code by a programmer into a well-formed program and the execution of
the code by a computer.
Therefore, variables are mutable, and EQness required by the standard
for conforming programs should be maintained. If there is a problem, I
think it is better to change the semantics of Common Lisp rather than
making compiling and loading special cases.
∂12-Mar-89 1031 CL-Compiler-mailer Issue CONSTANT-COMPILABLE-TYPES, version 7
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 12 Mar 89 10:31:25 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01319g; Sun, 12 Mar 89 10:24:17 PST
Received: by challenger id AA06634g; Sun, 12 Mar 89 10:19:40 PST
Date: Sun, 12 Mar 89 10:19:40 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903121819.AA06634@challenger>
To: sandra%defun@cs.utah.edu
Cc: cperdue@Sun.COM, cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 11 Mar 89 19:03:47 MST <8903120203.AA00900@defun.utah.edu>
Subject: Issue CONSTANT-COMPILABLE-TYPES, version 7
I think we can ignore non-Lisp functions. Here's why. First, we're
specifying Common Lisp, not C, so that only user-written functions in
Common Lisp have defined behavior under this proposal. Second, we're
only specifying what happens to well-formed programs that use the
built-in Common Lisp functions and etc (in the old days, the 775 magic
symbols). A proposal I have on the CL-cleanup table is that any
alteration of these magic functions has undefined consequences, except
where explicitly allowed. Therefore, the only important part of a
built-in CL function is its name, which is easy to dump.
That is, if you only have to dump its name, it doesn't matter what
language the body is in, and no well-defined programs alter those
definitions.
This is an example of what I mean by a conservative approach.
-rpg-
∂12-Mar-89 1032 Common-Lisp-Object-System-mailer Issue: LOAD-OBJECTS (Version 3)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 12 Mar 89 10:32:40 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01322g; Sun, 12 Mar 89 10:25:36 PST
Received: by challenger id AA06637g; Sun, 12 Mar 89 10:20:59 PST
Date: Sun, 12 Mar 89 10:20:59 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903121820.AA06637@challenger>
To: sandra%defun@cs.utah.edu
Cc: CL-Cleanup@sail.stanford.edu, CL-Compiler@sail.stanford.edu,
Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sat, 11 Mar 89 18:42:56 MST <8903120142.AA00878@defun.utah.edu>
Subject: Issue: LOAD-OBJECTS (Version 3)
Sandra's idea of two generic functions, one producing components and the
other doing construction/further initialization has some merits aside
from the question of dumping functions. I think we should consider it.
-rpg-
∂12-Mar-89 1045 CL-Compiler-mailer Re: Issue CONSTANT-COMPILABLE-TYPES, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Mar 89 10:45:41 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA26164; Sun, 12 Mar 89 11:43:13 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA01463; Sun, 12 Mar 89 11:43:11 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903121843.AA01463@defun.utah.edu>
Date: Sun, 12 Mar 89 11:43:10 MST
Subject: Re: Issue CONSTANT-COMPILABLE-TYPES, version 7
To: Richard P. Gabriel <rpg@lucid.com>
Cc: sandra%defun@cs.utah.edu, cperdue@Sun.COM, cl-compiler@sail.stanford.edu
In-Reply-To: Richard P. Gabriel <rpg@lucid.com>, Sun, 12 Mar 89 10:19:40 PST
Hmmm. I suppose it would work to dump the troublesome functions by
name, assuming of course that you can determine what the name is.
What do you do for an anonymous function?
To me, the real question is whether there are benefits from dumping
constant functions that would justify all the work involved for
implementors. I guess I would take more seriously your arguments
about them deserving better treatment at the hands of the compiler if
you were also proposing to require them to have a PRINTed
representation such that they can be READ in again. After all, such
non-Lispy things as pathnames and arrays get better treatment than
functions....
-Sandra
-------
∂12-Mar-89 1111 CL-Compiler-mailer Issue CONSTANT-COMPILABLE-TYPES, version 7
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 12 Mar 89 11:11:37 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01350g; Sun, 12 Mar 89 11:04:27 PST
Received: by challenger id AA06691g; Sun, 12 Mar 89 10:59:49 PST
Date: Sun, 12 Mar 89 10:59:49 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903121859.AA06691@challenger>
To: sandra%defun@cs.utah.edu
Cc: sandra%defun@cs.utah.edu, cperdue@Sun.COM, cl-compiler@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Sun, 12 Mar 89 11:43:10 MST <8903121843.AA01463@defun.utah.edu>
Subject: Issue CONSTANT-COMPILABLE-TYPES, version 7
Several (most?) implementations have back pointers from the compiled
function object to the symbol for built-in functions to aid debugging.
Nevertheless, many (all?) implementations encode the starting address
of the code object, which can easily (if it doesn't already) contain
all the information needed to retrieve the function name.
Printing functions? Well, the straightforward representation of them
already works more or less (list structure). Should we extend this?
Maybe, I haven't thought about it too much.
-rpg-
∂12-Mar-89 2014 Common-Lisp-Object-System-mailer Re: remote environments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 12 Mar 89 20:13:58 PST
Received: from Semillon.ms by ArpaGateway.ms ; 12 MAR 89 20:00:24 PST
Date: Sun, 12 Mar 89 20:00 PST
From: Gregor.pa@Xerox.COM
Subject: Re: remote environments
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Sandra J Loosemore
<sandra%defun@cs.utah.edu>, David N Gray <Gray@DSG.csc.ti.com>, Patrick
Dussud <dussud@lucid.com>
cc: Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>, cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-5.text.newest
In-Reply-To: <19890307023706.3.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19890309185905.3.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<8903100017.AA10108@defun.utah.edu>,
<2814540528-3314903@Kelvin>,
<19890310174955.3.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<8903101804.AA10718@defun.utah.edu>,
<8903101807.AA03577@challenger>,
<19890310194038.9.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<8903101949.AA10788@defun.utah.edu>,
<8903102056.AA10809@defun.utah.edu>,
<8903102240.AA03941@challenger>,
<2814562184-4740019@Kelvin>,
<8903111615.AA00548@defun.utah.edu>,
<2814639239-9369595@Kelvin>,
<19890311223604.9.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19890311225826.2.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19890311230120.3.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19890311230257.4.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19890311232009.6.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<19890311232035.7.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<8903120019.AA00810@defun.utah.edu>
Message-ID: <19890313040005.0.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
In this message I question, once again, the existence of remote
metaobjects. I may be behind the times here, but since no one answered
the long message I sent about why we could do without remote metaobjects
I am still stuck at that point.
Date: Thu, 23 Feb 89 18:38:01 CST
From: David N Gray <Gray@DSG.csc.ti.com>
* Can a MAKE-INSTANCE be done by a macro expander, DEFCONSTANT, or "#."?
Date: Mon, 6 Mar 89 21:37 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I think it would be much nicer if we could make compile-time classes
instantiable. However, I agree that it would not ruin the language to
omit that feature if we can't figure out how to do it.
Date: Fri, 10 Mar 89 16:49:44 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> One way to look at this would be to
> say that it is implementation-dependent whether FINALIZE-INHERITANCE
> works or signals an error when given a class defined in the
> compile-time environment.
I don't understand these comments. It seems to me that the only real
questions are "is there a remote class object?" and "if so, how are
remote functions represented?".
If there is a remote class object then we must solve what I previously
previously called the `splicing' problem. That remote class object must
have pointers to other class objects which represent its superclasses.
If that is the case, then to some extent that remote class will be
instantiable. Any class that has direct supers can be finalized
provided that none of the supers are forward referenced. Since it can
be finalized, allocate-instance can be called. So, the only real
question is whether the initfunctions can be called. From the user's
point of view, that translates into whether make-instance can be called.
Date: Mon, 6 Mar 89 21:37 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
When you compile-file a DEFMETHOD, a method metaobject is created but it
is not added to the generic-function metaobject in the local environment.
Instead it is added to a different generic-function metaobject created
in the remote environment. That's my model of what has to happen. Note
that this should be completely consistent with the way that compile-file
of a DEFCLASS, with a direct superclass whose name is defined in the
local environment and not in the remote environment, does not add the
new class metaobject to the direct subclasses of the local superclass,
but rather to a different object. (I realize we haven't agreed on what
this paragraph says, or even seen a coherent proposal, yet. I'm just
telling you my model.)
Yes, this is the `splicing' problem which must be solved to have remote
metaobjects.
In the past there has been some controversy about whether the remote
environment can inherit from the local environment. I think this is
crystal clear: since some user-defined classes have STANDARD-OBJECT
as a direct superclass, and STANDARD-OBJECT is not defined in the same
file, the remote environment is clearly inheriting from the local
environment. Different implementations might want to address the
details of this differently, but I think it's clear that there has to
be provision for it in the metaobject model. It makes things more
complicated, but that's unavoidable.
More splicing problems.
Date: Fri, 10 Mar 89 16:49:44 CST
From: David N Gray <Gray@DSG.csc.ti.com>
> This is an interesting idea, but I think it's too restrictive. Here's a
> plausible and many-times proposed application for metaobjects which
> would not be possible if we adopted this idea. Suppose you made an
> optimizing compiler that is allowed to assume that no class
> redefinitions, no method redefinitions, and no newly-defined subclasses
> will be created at run time. The compiler is to take advantage of this
I certainly don't want to prevent any implementation from doing that.
The real issue is what is the minimal functionality that all
implementations must support.
As Moon says in a later message, the issue here is not what the
implementation can do, its what portable programs can do. It needs to
be the case that one can write a portable, metaobject `compiler'. Many
people have wanted to do this. People currently do this with PCL which
surely has no remote metaobjects.
But, do we need remote metaobjects to do this? I have argued before
that we don't. I believe it would be a reasonable restriction on
such portable programs that the program they are `compiling' be loaded
before it can be compiled. No one has shown me why that isn't the case.
But, what I know wonder is whether it would be a reasonable restriction
on implementors. Because, with this metaobject stuff, we can specify
minimal behavior, but we can't specify minimally. If we specify that
there are no remote metaobjects, then implementations are going to have
to prevent themselves from ever instantiating remote versions of
portable metaobjects. Moreover they will have to be certain that user's
can't get their hands on remote metaobjects. This will make life more
complicated for implementations, I don't know how much more complicated.
On the other hand, solving the splicing problem will also be complicated
for implementations, and for the specification as well.
-------
∂13-Mar-89 0653 Common-Lisp-Object-System-mailer Re: remote environments
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89 06:53:16 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
id AA15174; Mon, 13 Mar 89 07:44:33 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
id AA02017; Mon, 13 Mar 89 07:44:17 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131444.AA02017@defun.utah.edu>
Date: Mon, 13 Mar 89 07:44:15 MST
Subject: Re: remote environments
To: Gregor.pa@Xerox.COM
Cc: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>,
Sandra.J.Loosemore%defun@cs.utah.edu, <sandra%defun@cs.utah.edu>,
David N Gray <Gray@DSG.csc.ti.com>, Patrick%defun@cs.utah.edu,
Dussud <dussud@lucid.com>, Kim A. Barrett <IIM%ECLA@ECLC.USC.EDU>,
cl-compiler@sail.stanford.edu,
common-lisp-object-system@sail.stanford.edu
In-Reply-To: Gregor.pa@Xerox.COM, Sun, 12 Mar 89 20:00 PST
> Date: Sun, 12 Mar 89 20:00 PST
> From: Gregor.pa@Xerox.COM
>
> If there is a remote class object then we must solve what I previously
> previously called the `splicing' problem. That remote class object must
> have pointers to other class objects which represent its superclasses.
> If that is the case, then to some extent that remote class will be
> instantiable. Any class that has direct supers can be finalized
> provided that none of the supers are forward referenced. Since it can
> be finalized, allocate-instance can be called. So, the only real
> question is whether the initfunctions can be called. From the user's
> point of view, that translates into whether make-instance can be called.
At least three of us (Moon, Gray, and myself) appear to agree that
DEFMETHOD should not make the method function callable at compile time
(by analogy to DEFUN). If you're using the term "initfunctions" to
refer to things like the SHARED-INITIALIZE method, then no, they can't
be called at compile-time by default.
Of course, if you really those methods to be callable at compile time,
you can always wrap an explicit (EVAL-WHEN (EVAL COMPILE LOAD) ...)
around both the class and method definitions. Alternatively, you'd
probably put the definitions in another file and load it before
compiling the file that wants to instantiate that class at compile
time.
Personally, I think we could leave the issue of whether remote classes
exist or are instantiable unspecified for now. It would give those of
you who are trying to sort out the meta-object protocol more freedom,
and I don't think it would place an unreasonable burden on programmers.
> But, do we need remote metaobjects to do this? I have argued before
> that we don't. I believe it would be a reasonable restriction on
> such portable programs that the program they are `compiling' be loaded
> before it can be compiled. No one has shown me why that isn't the case.
I guess this is pretty much the same thing as I was saying above. The
one reservation I have (that others have also expressed) is that the
common practice of a file containing a class definition followed by
method definitions on that class should compile properly without
having to do any magic with pre-loading the file or wrapping
EVAL-WHENs around everything. Would that cause problems for the
meta-object protocol?
-Sandra
-------
∂13-Mar-89 0853 X3J13-mailer issue COMPILER-VERBOSITY, version 6
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 Mar 89 08:53:16 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Mon, 13 Mar 89 11:48:42 EST
Date: Mon, 13 Mar 89 11:50 EST
From: Barry Margolin <barmar@Think.COM>
Subject: issue COMPILER-VERBOSITY, version 6
To: cl-compiler@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131546.AA02078@defun.utah.edu>
Message-Id: <19890313165001.9.BARMAR@OCCAM.THINK.COM>
I see the benefit of :PRINT, but do we really need :VERBOSE? What's the
difference between
(compile path :verbose t)
and
(format t "~&Compiling file ~A...~%" path)
(compile-file path)
(format t "~&done.~%")
If any users want to have this controlled by a global variable, they can
do what we (Thinking Machines) did years ago and package it up in their
own function. At this stage of the game I don't see the need to add
gratuitous features like this.
:PRINT is less gratuitous because it implements a feature that the user
can't add himself.
barmar
∂13-Mar-89 1023 CL-Compiler-mailer Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Mar 89 10:23:31 PST
Received: by ti.com id AA16774; Mon, 13 Mar 89 12:21:56 CST
Received: from Kelvin by tilde id AA26537; Mon, 13 Mar 89 12:14:31 CST
Message-Id: <2814804793-2851395@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Mon, 13 Mar 89 12:13:13 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Cc: David N Gray <Gray@DSG.csc.ti.com>, cl-compiler@sail.stanford.edu,
"David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>,
"Kim A. Barrett" <IIM%ECLA@ECLC.USC.EDU>,
KMP@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: issue MACRO-ENVIRONMENT-EXTENT, version 2
In-Reply-To: Msg of Sat, 11 Mar 89 16:29:06 MST from sandra%defun@cs.utah.edu (Sandra J Loosemore)
> How about some wording like:
>
> The extent of the environment objects passed to MACROEXPAND or
> MACROEXPAND-1 by COMPILE-FILE, COMPILE, and EVAL is the dynamic extent
> during which the macro and its expansion are processed. In
> particular, the extent includes the expansion of any other macro calls
> appearing lexically within the form returned from MACROEXPAND or
> MACROEXPAND-1.
That would be fine.
> I think this would fit in with issue SYNTACTIC-ENVIRONMENT-ACCESS, but
> I'm still confused about why you would still need COPY-ENVIRONMENT.
COPY-ENVIRONMENT would only be needed if there are implementations using
stack list environments that disappear as soon as the macro expander
returns. Kent, does Symbolics need this?
> One other thing that's still not really clear to me is why you think
> this is better than just saying they have (or can be copied to have)
> indefinite extent. It would make the typed-variable example work but
> not be of much use for macro-caching. Can you provide a more specific
> rationale than just saying that it gives implementors more flexibility?
I want to be able to do something like this:
(defun VARIABLE-KIND (variable &optional environment)
(if (compiler:compilation-environment-p environment)
(case (compiler:var-type (compiler:lookup-var variable compiler:vars))
...)
;; else handle interpreter environment
...))
where the attributes of the variable are actually found in special
variable compiler:vars instead of in the environment object. This would
permit implementing proposal SYNTACTIC-ENVIRONMENT-ACCESS without
needing to redesign the compiler's data structures.